Git commands
How to finish a Git cherry-pick after fixing a conflict
git cherry-pick --continue: finishing a pick that conflicted
How to use this page
- slider / ▶Drag the slider, or press play, to watch the command happen. Before and After jump to either end.
- ← → · spaceStep through a multi-step command; space toggles Before / After.
- APlay or pause the loop (the page opens playing). Any manual input takes over.
- hoverA commit shows its message, author, date and parents, with its history highlighted.
- clickCopies the commit sha.
- ctrl + wheelZoom around the cursor (pinch on a trackpad). Double-click resets the view.
- EscStop playback, reset the view, close this menu.
- shareThe Share button copies a link to this graph, copies it as an image, downloads PNG/SVG/page, or posts it. #before, #after or #step=N in the link pins the state.
git-sim visually simulates any Git command in your own repos - from your terminal, IDE, or AI.
Table of Contents
- Introduction
- What is git cherry-pick --continue?
- How the pick stopped
- Watch it happen
- Before and after
- Is it safe?
- How to undo it
- Picking several commits
- Useful forms
- Try it on your repository
- Common questions
- Summary
- Next steps
- Related commands
Introduction
If you cherry-pick commits between branches often, sooner or later one won't apply cleanly. The branch you're picking onto has changed the same lines, and Git stops with "could not apply" and a conflict to sort out. After you've fixed the file, the pick is still waiting to be committed. git cherry-pick --continue is how you tell Git you're done and it can make the commit.
In this article, we'll:
- Resolve a conflict from picking "Space out the header links" onto
main - Watch
git cherry-pick --continuemake the new commit and movemainonto it - Cover how a range of picks stops at each conflict, and
--skipfor a commit you don't want after all
What is git cherry-pick --continue?
git cherry-pick --continue finishes a cherry-pick that stopped on a conflict. It takes what you've staged, commits it with the original commit's message and author, and moves your branch onto the new commit. If you were picking several commits, it then carries on with the next one.
A plain git cherry-pick does all of this in one go when the change applies cleanly. --continue is the second half of the same command, run after you've done the part Git couldn't.
How the pick stopped
Our sample repo has a cherry-pick of feature's last commit onto main that stopped on a conflict in styles.css, now resolved and staged. main is on "Switch the header to grid" (ada2e79), which set styles.css to header { display: grid; }. The last commit on feature, "Space out the header links" (791fd8e), changed that same line to header { display: flex; gap: 12px; }. Running git cherry-pick 791fd8e on main can't apply that change cleanly, so Git writes both versions into styles.css between conflict markers, records the commit it was picking in .git/CHERRY_PICK_HEAD, and stops. git status says:
You are currently cherry-picking commit 791fd8e.
(fix conflicts and run "git cherry-pick --continue")
We resolve it by keeping the grid and taking the gap:
header { display: grid; gap: 12px; }
and then stage it with git add, which is how Git learns the conflict is resolved.
Watch it happen
Here's git cherry-pick --continue, with that resolution staged:
- Before:
HEADis attached tomainatada2e79"Switch the header to grid", andfeaturepoints at791fd8e"Space out the header links". The resolvedstyles.cssis staged but not committed yet. - Git creates a new commit on
mainwith the message of "Space out the header links" and the resolved changes from the index, withada2e79as its parent. It has a new id,25da354. mainmoves to the new commit, andHEADmoves with it.featureand its four commits are unchanged.
Before and after
The after graph has "Space out the header links" twice, once on each branch. They're different commits with different hashes, 791fd8e on feature and 25da354 on main, and the one on main holds our resolved line rather than feature's original. Git's output:
The raw git output, if you want to read along in text
git log --oneline --graph --all
before
* 791fd8e (feature) Space out the header links
* 1117a34 Add search tests
* e5869f0 Fix typo in search box
* fc19889 Add search box
| * ada2e79 (HEAD -> main) Switch the header to grid
| * 8c02d5b Update dependencies
| * a0b2db3 Add user settings page
|/
* 96c4fc2 Fix header layout
* ae65976 Add login page
* 3e1ffe4 Add project skeleton
* 4114b2c Initial commitafter
* 25da354 (HEAD -> main) Space out the header links
* ada2e79 Switch the header to grid
* 8c02d5b Update dependencies
* a0b2db3 Add user settings page
| * 791fd8e (feature) Space out the header links
| * 1117a34 Add search tests
| * e5869f0 Fix typo in search box
| * fc19889 Add search box
|/
* 96c4fc2 Fix header layout
* ae65976 Add login page
* 3e1ffe4 Add project skeleton
* 4114b2c Initial commitwhat git printed
[main 25da354] Space out the header links
Date: Wed May 1 22:00:00 2024 +0000
1 file changed, 1 insertion(+), 1 deletion(-)Notice the Date: line. A cherry-pick keeps the original commit's author and author date, and Git mentions the date because it doesn't match when the commit was made. git status goes from M styles.css to clean.
Is it safe?
Safe git-sim pre-flight
Creates the commit with your resolution for 791fd8e Space out the header links; main moves to it.
The way back
Undo the new commit afterwards with: git reset --hard ORIG_HEAD
It is. It adds one commit to main and doesn't touch feature or any existing commit. As with any conflict, check that the file you staged is really the version you want. --continue commits whatever is in the staging area, conflict markers included if you left them in.
How to undo it
If you haven't pushed, drop the picked commit by moving main back one commit:
git reset --hard HEAD~1
main goes back to ada2e79 and styles.css back to the grid-only version. --hard also throws away any uncommitted edits, so check git status first.
If the picked commit has already been pushed, use git revert on it to add a commit that reverses it instead.
Picking several commits
When you cherry-pick a range of commits, like git cherry-pick 96c4fc2..feature, Git applies them one at a time, oldest first. Every time one conflicts, it stops, and you go through the same routine: fix the file, git add it, git cherry-pick --continue. Git commits that pick and moves on to the next commit in the range, until the range is done or the next conflict.
Sometimes, looking at the conflict, you realize you don't want that commit on this branch at all. Maybe main already has an equivalent change. git cherry-pick --skip drops the commit that conflicted and carries on with the rest of the range. And if the whole thing is going sideways, git cherry-pick --abort puts your branch back to where it was before the first pick.
Useful forms
git cherry-pick --skipleaves out the commit that conflicted and moves on.git cherry-pick -x <commit>adds a "(cherry picked from commit ...)" line to the new commit's message, which makes the two easier to connect later. Add it when you start the pick, not at--continue.git commitalso commits a conflicted pick, but in a range you'd still needgit cherry-pick --continueafterwards to move on to the next commit.
Try it on your repository
pip install git-sim
git-sim cherry-pick --continue
git-sim runs the command in a copy of your repository and draws the commit it would make, so your own stopped pick stays as it is.
Common questions
What does git cherry-pick --continue do?
It commits the change you were cherry-picking, with your conflict resolution in it, and moves your branch onto the new commit. In a range, it then goes on to the next commit.
Does the picked commit keep the original author?
Yes. The new commit keeps the original's author, author date and message. You become the committer, and the commit date is when you ran --continue. The git cherry-pick documentation lists the options that change this, like -x and --signoff.
What is the difference between --continue and --skip?
--continue commits your resolution of the commit that conflicted. --skip drops that commit entirely and moves on to the next one in the range.
Why does git cherry-pick --continue say there is nothing to commit?
Your resolution made the file identical to what main already had, so the pick would add an empty commit. If you don't need the commit, run git cherry-pick --skip. If you want it anyway, git commit --allow-empty keeps it.
Summary
In this article, we resolved the styles.css conflict from picking "Space out the header links" onto main, watched git cherry-pick --continue make the new commit and move main and HEAD onto it, and covered ranges and --skip.
Next steps
git cherry-pick covers picks that apply cleanly. git cherry-pick --abort is the way out when you'd rather not resolve the conflict.
Related commands
- git cherry-pick, the pick that stopped
- git cherry-pick --abort, to call the pick off instead
- git cherry-pick A..B, where one conflict per commit can add up
- git add, to mark the conflict resolved
- git merge --continue, the same step for a merge
- git reset --hard, to drop the picked commit if you change your mind
