Git Cheatsheet

Merging

Use this Git reference while you build software engineering projects, review code for technical interview prep, or polish examples for a software engineer resume.

Basic Merging

git merge <branch>              # Merge <branch> into the current branch
git merge origin/<branch>       # Merge a remote-tracking branch
git merge <branch> --no-ff      # Force a merge commit (disable fast-forward)
git merge <branch> --ff-only    # Abort if not a fast-forward
git merge <branch> --squash     # Squash all commits into staged changes (no commit yet)
git merge <branch> -m "msg"     # Custom merge commit message
git merge --no-commit <branch>  # Merge but stop before committing (inspect first)
git merge --abort               # Abort an in-progress merge with conflicts
git merge --continue            # Continue after resolving conflicts

Merge Strategies

git merge -s recursive <branch>         # Default for two-branch merge
git merge -s ort <branch>              # Newer default (Git ≥2.34), faster
git merge -s octopus branch1 branch2   # Merge multiple branches at once (no conflicts allowed)
git merge -s ours <branch>             # Keep our version entirely (discard theirs)
git merge -s subtree <branch>          # For subtree merges

Strategy Options (-X)

git merge -X ours <branch>      # Prefer our side on conflict (auto-resolve)
git merge -X theirs <branch>    # Prefer their side on conflict (auto-resolve)
git merge -X patience <branch>  # Use "patience" diff algorithm (better for large diffs)
git merge -X ignore-all-space <branch>  # Ignore whitespace differences

Fast-Forward vs. Merge Commit

Fast-forward (no merge commit):
  main ---A---B
                \
  feature        C---D
  result: main → A---B---C---D

No-FF (explicit merge commit):
  main ---A---B-----------M
                \         /
  feature        C---D---
# Prefer explicit merge commits (common in team workflows)
git config --global merge.ff false
git config branch.main.mergeoptions "--no-ff"

Resolving Merge Conflicts

When a conflict occurs, Git marks the affected files and halts:

git status                      # See which files have conflicts
git diff                        # Show conflict markers in working tree

Conflict marker format:

<<<<<<< HEAD
  content from current branch
=======
  content from incoming branch
>>>>>>> feature/login

With merge.conflictstyle=diff3:

<<<<<<< HEAD
  our version
||||||| base
  original (common ancestor)
=======
  their version
>>>>>>> feature/login
git mergetool                   # Open configured merge tool for all conflicts
git mergetool --tool=vscode     # Use a specific tool
git checkout --ours <file>      # Accept our version of a file entirely
git checkout --theirs <file>    # Accept their version of a file entirely
# After resolving:
git add <file>                  # Mark conflict resolved
git commit                      # Complete the merge
git merge --abort               # Or abort and undo everything

Viewing Merge Status

git log --merges                # Show only merge commits
git log --no-merges             # Exclude merge commits
git log --graph --oneline --all # Visual branch/merge graph
git show HEAD                   # Inspect the merge commit

Squash Merge

Combines all commits from a branch into a single set of staged changes:

git merge --squash <branch>     # Stage all changes but don't commit
git commit -m "squash merge: feature/login"
# The original branch commits won't appear in the target branch history

Merge vs. Rebase Decision

SituationPrefer
Shared/public branchesmerge (preserves history)
Local feature branchesrebase (clean linear history)
Auditing team workmerge --no-ff (explicit merge commits)
CI/CD pipelinesmerge --squash (atomic, one commit per feature)

Cherry-Pick (Selective Merge)

Applies specific commits to the current branch:

git cherry-pick <sha>           # Apply a single commit
git cherry-pick <sha1> <sha2>   # Apply multiple specific commits
git cherry-pick <sha1>..<sha2>  # Apply a range (exclusive start)
git cherry-pick <sha1>^..<sha2> # Apply a range (inclusive start)
git cherry-pick -n <sha>        # Apply changes but don't commit (--no-commit)
git cherry-pick -x <sha>        # Append "cherry picked from commit <sha>" to message
git cherry-pick --abort         # Abort on conflict
git cherry-pick --continue      # Continue after resolving conflict
git cherry-pick --skip          # Skip current conflicting commit

Merge Commit Message Conventions

# Typical auto-generated merge commit message:
"Merge branch 'feature/login' into main"

# Override it:
git merge <branch> -m "feat: merge login feature (#42)"

Gotchas

git merge --squash does NOT create a merge commit. The source branch is not tracked as merged, so git branch --merged won't list it and it can be accidentally merged again later.

git merge -s ours discards ALL of the other branch's changes — it's for marking a branch as "merged" without taking any of its content.

After git merge --abort, you're back to the pre-merge state. This only works while a merge is in progress (.git/MERGE_HEAD exists).