Skip to content

Practice: Cherry-pick and stash

Answer each in your own words first, then open the answer to check.

Q1. What does git cherry-pick abc1234 do, mechanically? What’s the SHA of the resulting commit?

Show answer

It takes the diff that commit abc1234 introduced (the difference between abc1234 and its parent), applies that diff to your current branch’s HEAD, and creates a NEW commit on your current branch with that diff. The new commit has the same author info and message as abc1234 but a DIFFERENT SHA (because the parent is different, the content is different, the SHA is computed fresh).

Q2. What does the -x flag add to a cherry-picked commit, and why is it useful?

Show answer

It adds a line to the commit message: (cherry picked from commit abc1234). This is useful for traceability, six months later, when someone is debugging the cherry-picked commit and wonders where it came from, they can find the original. Many teams require -x on all cherry-picks as policy.

Q3. You start a cherry-pick and hit a conflict. What are your three options?

Show answer

git cherry-pick --continue (after resolving the conflict markers and running git add on the resolved files), git cherry-pick --skip (skip this particular commit if you were cherry-picking multiple), or git cherry-pick --abort (give up entirely and restore the working tree to its pre-cherry-pick state).

Q4. Why does git cherry-pick abc1234..def5678 NOT include commit abc1234?

Show answer

Git’s range syntax A..B is exclusive of A and inclusive of B by convention, it means “commits reachable from B but not from A,” so A itself is excluded. To include abc1234, use abc1234^..def5678 (the caret means “the parent of,” so the range starts just before abc1234, making abc1234 the first included commit).

Q5. What’s the difference between git stash pop and git stash apply?

Show answer

pop applies the most recent stash AND removes it from the stack. apply applies the most recent stash but LEAVES it on the stack. Use apply when you want to keep the stash as a safety net (in case the apply doesn’t go as expected). Use pop when you’re confident the apply will work cleanly.

Q6. When would you reach for git stash branch <name> instead of git stash pop?

Show answer

When the working tree (or main) has moved on significantly since you stashed, and popping the stash would create messy conflicts. git stash branch creates a new branch starting from the commit you were on when you stashed, then applies the stash there. You get a clean branch with your stashed work in its original context, no conflicts with divergent main.

Q7. What’s the danger of cherry-picking the same commit twice onto the same branch?

Show answer

You get two commits with the same content but different SHAs. The duplicates don’t break anything immediately, but they confuse anyone reading history later (“why is the same fix here twice?”) and may cause merge conflicts down the road. If you accidentally double-pick, fix with git reset --hard HEAD~1 to drop the second copy.

Q8. Why is committing WIP to a branch usually safer than stashing for multi-day work?

Show answer

Stashes are LOCAL ONLY, they don’t push, they’re not visible to teammates, and if your laptop dies they’re gone. WIP commits on a branch can be pushed to remote, visible to teammates, recoverable from any machine, and survive disk failure. Stash is appropriate for short context switches (minutes to a few hours); for longer pauses or any high-value WIP, commit and push.

You have a local clone of a project. Walk through these steps with a real repo (or visualize them mentally if you don’t have one handy).

  1. On main, create a file notes.txt with one line, commit it. Note the SHA of this commit.
  2. Create a branch feature/extra off main. On feature/extra, add a second line to notes.txt and commit.
  3. Switch back to main. Cherry-pick the commit from feature/extra (use its SHA).
  4. Look at notes.txt on main. Both lines should be there.
  5. Run git log main --oneline and confirm there are two commits on main but only one on feature/extra was the source.

Now extend:

  1. On main, add a third line to notes.txt and commit.
  2. Switch to feature/extra. Cherry-pick the third-line commit from main.
  3. Confirm feature/extra now has all three lines.
  1. On main, create a file config.txt with the line port=8080. Commit.
  2. Create a branch feature/port-change. Change the line to port=9090. Commit.
  3. Switch back to main. Change the line to port=8443. Commit.
  4. Try git cherry-pick of the feature/port-change commit onto main.
  5. You should hit a conflict. Inspect the conflict markers.
  6. Resolve by keeping port=8443 (decide that main’s value wins). Run git cherry-pick --skip instead of --continue to abandon this particular pick.
  7. Confirm main’s history shows the cherry-pick attempt is gone.
  1. On main, modify any file (add a line). Don’t commit.
  2. Run git stash push -m "WIP test stash".
  3. Run git status, should be clean.
  4. Run git stash list, should show your stash.
  5. Run git stash show -p stash@{0}, should show your diff.
  6. Pop the stash with git stash pop. Your changes should reappear.
  7. Run git stash list, should be empty.

Now extend with apply:

  1. Modify the file again. Run git stash push -m "WIP 2".
  2. This time run git stash apply instead of pop. Changes reappear.
  3. Run git stash list, the stash is STILL there.
  4. Drop it with git stash drop.
  1. On main, modify a file and stash with git stash push -m "old stash".
  2. Make 2-3 unrelated commits on main after stashing.
  3. Now try git stash pop. Resolve the conflict (or abort with git checkout -- .).
  4. Instead, use git stash branch experiment-revive stash@{0} (you may need to re-create the stash if you dropped it).
  5. You should land on a new branch starting from the commit you were on when you stashed, with the stashed changes applied cleanly.

Scenario A: You’re maintaining a library. A user reports a CVE. You fix it on main and merge. You also need to backport to release/v2.4 and release/v1.8. The fix applies cleanly on v2.4 but conflicts on v1.8. Walk through your approach for each branch.

Show answer

For v2.4: standard backport flow. git checkout release/v2.4, git pull, create a backport branch git checkout -b backport/cve-X-v2.4, git cherry-pick -x <fix-sha> (clean apply), run tests locally, push, open PR against release/v2.4 with reviewer who knows that codebase. After merge, cut a v2.4.N+1 release.

For v1.8: same setup, but the cherry-pick conflicts. Read the conflict markers carefully. Don’t try to mechanically resolve line-by-line; understand what the original fix is DOING conceptually (sanitizing input, fixing a race, etc.) and re-apply that concept using v1.8’s code structure. Add a comment in the code referencing the original fix SHA for future debuggers. Tests on v1.8 must pass. PR with extra-careful review (a reviewer familiar with both v1.8 and the original fix). After merge, cut a v1.8.N+1 release.

Scenario B: You’re 90 minutes into writing a new feature. Three files modified, nothing committed. Your team lead pings about a production bug they need help debugging, they want you to switch context for 15-20 minutes. Walk through the commands you’d run before and after the context switch.

Show answer
Terminal window
# Before the switch
git stash push -m "WIP feature/X - 90 min in, three files mid-edit"
git checkout main
git pull # get latest in case the bug fix needs to start from current main
# ... do the 15-20 minute help / debugging ...
# ... maybe make a hotfix commit on a branch and push ...
# After
git checkout feature/X
git stash pop
# back where you were, three files modified, exactly as before

Scenario C: You’ve had a stash sitting around for a month. You don’t remember what’s in it. The branch you were on when you stashed has been deleted. Walk through how you’d inspect the stash and decide whether to recover it or drop it.

Show answer
Terminal window
# Inspect what's in it
git stash list # see the stash entry
git stash show -p stash@{N} # see the full diff
# Decide: is this still relevant?
# If yes, create a branch from where you were when stashed
# (even though the branch is deleted, the commit SHA in the stash header still exists)
git stash branch recover-old-feature stash@{N}
# If no, drop it
git stash drop stash@{N}

Scenario D: You spent two days on an experiment branch. Five commits. You decided the overall direction is wrong, BUT one of the commits is a useful standalone refactor. Walk through how you’d salvage just that commit before deleting the experiment branch.

Show answer
Terminal window
git log experiment/X --oneline # list all commits
# Identify the one good one (call it 7f9a44b)
git checkout main
git cherry-pick -x 7f9a44b # land just that one commit on main
# Verify it works
# Run tests, commit any needed adjustments
git branch -D experiment/X # safe to delete the rest of the experiment
Q. Cherry-pick `abc1234`
A.

Copies the diff of commit abc1234 onto your current branch as a NEW commit with a different SHA

Q. The `-x` flag on cherry-pick
A.

Adds (cherry picked from commit abc1234) to the new commit’s message, traceability for future debugging

Q. Cherry-pick conflict recovery
A.

Three options: --continue (after resolving), --skip (skip this commit, continue with range), --abort (give up entirely, working tree restored)

Q. Cherry-pick range exclusive start
A.

abc..def does NOT include abc; use abc^..def to include abc

Q. `git stash` (no message)
A.

Saves working tree + index changes to the stash stack, resets working tree to clean. Auto-generates an unhelpful name.

Q. `git stash push -m "message"`
A.

Same as git stash but with a descriptive name visible in git stash list. Recommended.

Q. `git stash -u`
A.

Include untracked files in the stash too. Default stash does NOT capture untracked files.

Q. `git stash pop`
A.

Apply most recent stash and REMOVE it from the stack

Q. `git stash apply`
A.

Apply most recent stash but KEEP it on the stack

Q. `git stash branch new-branch stash@{0}`
A.

Create a new branch starting from where you were when stashed, apply stash there. Cleanest recovery for old stashes.

Q. Cherry-pick danger
A.

Same commit cherry-picked twice = duplicate commits with different SHAs. Confusing history.

Q. Stash danger
A.

Stash is local-only, ephemeral, easy to lose. Don’t use for multi-day work. Commit to a branch instead.

Q. Cherry-pick right tool when...
A.

Specific commit needed on a divergent branch. Hotfix backport. Forward-port. Salvage from abandoned branch.

Q. Cherry-pick wrong tool when...
A.

All of branch X needs to go to branch Y (use merge). Commits have subtle dependencies on each other. Both branches will merge anyway.

Q. Stash right tool when...
A.

Short context switch (minutes to a few hours). Want to swap branches without committing. Want to test something quickly.

Q. Stash wrong tool when...
A.

Multi-day pause. Hand-off to teammate. Anything you’d be sad to lose if your laptop died.