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/logingit 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
| Situation | Prefer |
|---|---|
| Shared/public branches | merge (preserves history) |
| Local feature branches | rebase (clean linear history) |
| Auditing team work | merge --no-ff (explicit merge commits) |
| CI/CD pipelines | merge --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 --squashdoes NOT create a merge commit. The source branch is not tracked as merged, sogit branch --mergedwon't list it and it can be accidentally merged again later.
git merge -s oursdiscards 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_HEADexists).