Skip to content

Cheatsheet: Cherry-pick and stash

Git stores snapshots. Every other command is just navigating those snapshots.

GoalCommand
Pick one commit onto current branchgit cherry-pick <sha>
Pick with traceabilitygit cherry-pick -x <sha>
Pick multiple commitsgit cherry-pick <sha1> <sha2> <sha3>
Pick a range (exclusive start)git cherry-pick <sha-from>..<sha-to>
Pick a range (inclusive start)git cherry-pick <sha-from>^..<sha-to>
Pick without auto-committinggit cherry-pick --no-commit <sha>
Resume after resolving conflictgit cherry-pick --continue
Skip current commit during rangegit cherry-pick --skip
Abort entire cherry-pickgit cherry-pick --abort
Pick a merge commitgit cherry-pick -m 1 <sha> (rare)
GoalCommand
Save with descriptive messagegit stash push -m "WIP description"
Save including untracked filesgit stash push -u -m "WIP description"
List all stashesgit stash list
Show summary of a stashgit stash show stash@{0}
Show diff of a stashgit stash show -p stash@{0}
Apply most recent and removegit stash pop
Apply specific stash and removegit stash pop stash@{2}
Apply most recent, keep on stackgit stash apply
Apply specific, keep on stackgit stash apply stash@{2}
Drop a specific stashgit stash drop stash@{1}
Drop ALL stashes (dangerous)git stash clear
Create branch from a stashgit stash branch <branch> stash@{0}
SituationTool
One specific commit needed on another branchcherry-pick
Backport a hotfix to a release branchcherry-pick
All of branch X should land on branch Ymerge
Forward-port a release fix to main going forwardcherry-pick (small fix) or merge (entire release)
Salvage one good commit from an abandoned experimentcherry-pick
Both branches will be merged later anywaywait for merge, don’t cherry-pick
Commits depend on each other in subtle waysmerge (all of them) or rebase the group
SituationTool
Need to swap branches for 15 minutesstash
Need to pull latest, then continuestash
Trying a quick experimentstash
Going home for the day with half-done workWIP commit + push
Handing off to a teammateWIP commit + push
Multi-day project, not ready to commit cleanlyWIP commit on a feature branch (squash later)
Anything you’d be sad to lose if your laptop diedWIP commit + push
Terminal window
# Step 1-2: setup
echo "line 1" > notes.txt
git add notes.txt
git commit -m "initial notes"
MAIN_SHA=$(git rev-parse HEAD)
git checkout -b feature/extra
echo "line 2" >> notes.txt
git add notes.txt
git commit -m "add line 2"
FEATURE_SHA=$(git rev-parse HEAD)
# Step 3: switch back and cherry-pick
git checkout main
git cherry-pick $FEATURE_SHA
# notes.txt now has line 1 and line 2
# Step 4-5: verify
cat notes.txt # should show both lines
git log main --oneline # should show 2 commits, with the cherry-pick on top
# Step 6-8: reverse direction
echo "line 3" >> notes.txt
git add notes.txt
git commit -m "add line 3"
THIRD_SHA=$(git rev-parse HEAD)
git checkout feature/extra
git cherry-pick $THIRD_SHA
cat notes.txt # should show all three lines

Cherry-pick conflict drill, model walk-through

Section titled “Cherry-pick conflict drill, model walk-through”

The conflict in step 4-5 will look like:

<<<<<<< HEAD
port=8443
=======
port=9090
>>>>>>> abc1234... (your cherry-picked commit)

Resolving by keeping port=8443 and running git cherry-pick --skip (rather than --continue) means the cherry-pick is abandoned for THIS commit. The cherry-pick exits without producing a new commit. If you were picking multiple commits and only this one conflicted, the others would still be picked normally.

Terminal window
# Setup: stash and then advance main
echo "stashed work" > old-file.txt
git add old-file.txt
git stash push -u -m "old stash"
# Advance main with unrelated commits
echo "unrelated 1" > other.txt
git add other.txt
git commit -m "unrelated 1"
# ... a few more ...
# Now create the branch from the stash
git stash branch revive-old-work stash@{0}
# You're now on `revive-old-work`, starting from where you stashed
# The stash is applied cleanly (no conflict with main's drift)
# The stash is dropped from the stack
git status # shows the stashed changes as modifications
MistakeFix
Cherry-picked the same commit twicegit reset --hard HEAD~1 to drop the second copy
Cherry-pick stuck mid-conflict, want to give upgit cherry-pick --abort
Stash pop gave conflict, don’t want to deal with itgit checkout -- . to discard conflict state, stash still on stack
Stashed and immediately forgot the messagegit stash show -p stash@{0} to see the diff
Lost a stash with git stash dropRecovery via reflog is possible but tricky: git fsck --lost-found then inspect dangling commits
Cherry-pick should have been a mergegit reset --hard <pre-pick-sha> then git merge instead
Cherry-pick a commit and then realize you need its whole branchSame fix: reset, then merge the source branch

Rebase, deeper. Interactive rebase (git rebase -i HEAD~5) lets you reorder, squash, fixup, edit, or drop commits in a range. Used for cleaning up history before opening a PR (collapsing “WIP” commits into one clean commit). The lesson covers when rebase is safe (your local branch, not yet pushed) and when it’s dangerous (published commits other people have pulled). Closes Phase 3.