Table of Contents

Introduction

If you've cherry-picked a commit only to have Git stop with "could not apply" and a conflict you weren't expecting, you have two choices: resolve it, or back out. git cherry-pick --abort is backing out. It cancels the pick and returns your branch, your staging area and your files to the state they were in before you ran git cherry-pick.

In this article, we'll:

  1. Watch git cherry-pick --abort call off a pick of "Space out the header links" onto main
  2. See what it throws away, and why the graph doesn't change
  3. Cover --quit, which stops a range of picks but keeps the ones already done

What is git cherry-pick --abort?

git cherry-pick --abort cancels a cherry-pick that is in progress. Git remembers the commit it was picking in .git/CHERRY_PICK_HEAD, and for a range of commits it keeps its to-do list in .git/sequencer. --abort resets your branch, the staging area and the working directory to where they were before the pick started, and removes that state. Your branch doesn't gain a commit, and the commit you were picking is left alone on its own branch.

How the pick stopped

Our sample repo has a cherry-pick of feature's last commit onto main stopped on a conflict in styles.css. 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 the same line to header { display: flex; gap: 12px; }. So git cherry-pick 791fd8e on main stopped with both versions in styles.css between conflict markers, and git status says:

You are currently cherry-picking commit 791fd8e.
  (fix conflicts and run "git cherry-pick --continue")
  (use "git cherry-pick --skip" to skip this patch)
  (use "git cherry-pick --abort" to cancel the cherry-pick operation)

Watch it happen

Here's git cherry-pick --abort, with the conflict still unresolved:

  1. Before: HEAD is attached to main at ada2e79 "Switch the header to grid", and feature points at 791fd8e "Space out the header links". CHERRY_PICK_HEAD also points at 791fd8e, so Git remembers what it was picking. The pick stopped before creating a commit, and styles.css is unmerged.
  2. Git deletes CHERRY_PICK_HEAD and clears the conflict from the index.
  3. Git resets styles.css to its version in ada2e79, and the pick is over. No commit is created on main, and feature still points at "Space out the header links".

Before and after

The before and after pictures match, because a stopped cherry-pick lives in the staging area and working directory, not in the commit graph. The change is in git status --short --branch, which goes from

## main
UU styles.css

to

## main

styles.css is back to header { display: grid; }, without the markers. The abort prints nothing:

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 commit

after

* 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 commit

Is it safe?

Caution git-sim pre-flight

Calls off the cherry-pick: HEAD stays on ada2e79, and the staging area and working directory are reset to it. Nothing is committed.

What you would lose

  • your edits to styles.css since the cherry-pick stopped (not recoverable)

The way back

  • Run the same cherry-pick again to get the conflict back; the edits themselves can't be recovered.

Your commits are safe: nothing is committed, removed or moved. What goes is anything you did to styles.css after the pick stopped. If you'd half-resolved the conflict, that work was never stored anywhere, so it's gone. The commit you were picking is still on feature, so you can always try again.

When a pick conflicts in a file I didn't expect it to touch, I usually abort right away and run git show on the commit before trying again. More than once that showed me the commit depended on an earlier one on the same branch, and what I really wanted was to pick both.

How to undo it

Nothing was committed, so undoing an abort means starting the pick again:

git cherry-pick 791fd8e

Git stops on styles.css exactly as before. This time you can resolve it, git add the file and finish:

Before trying again, git show 791fd8e is a quick way to see exactly what the commit changes, and whether it expects something main doesn't have.

--abort versus --quit

With a single commit, --abort and --quit end up close. The difference matters when you're picking a range of commits. Say you run git cherry-pick 96c4fc2..feature to apply all four of feature's commits to main, and the first three apply cleanly. main now has three new commits. Then "Space out the header links" conflicts.

  • git cherry-pick --abort takes you back to before the whole range. main returns to ada2e79, and the three new commits that had already gone through are dropped along with the one that conflicted.
  • git cherry-pick --quit just stops. main keeps the three new commits, Git forgets the rest of the range, and the conflicted styles.css is left as it is for you to resolve or clean up yourself.

Reach for --quit when the first part of a range was what you wanted and the rest can wait. The git cherry-pick documentation describes --abort as returning "to the pre-sequence state", which is the whole range, not just the last commit. If you abort and then wish you hadn't, git reflog still has the commits that were picked before the conflict.

Useful forms

  • git cherry-pick --skip drops only the commit that conflicted and carries on with the rest of a range.
  • git cherry-pick --quit stops the sequence and keeps everything picked so far.
  • git revert --abort does the same job for a revert that stopped on a conflict. Revert and cherry-pick share the same machinery in Git.

Try it on your repository

pip install git-sim
git-sim cherry-pick --abort

git-sim runs the abort in a copy of your repository and draws the result, so your own stopped pick is not touched.

Common questions

What does git cherry-pick --abort do?

It cancels a cherry-pick that stopped on a conflict. Your branch stays on the commit it was on before the pick, and the staging area and working directory go back to match it.

Will git cherry-pick --abort lose my changes?

It discards the picked change and anything you did to the conflicted files after the pick stopped. Your commits, and the commit you were picking, are not affected.

What is the difference between git cherry-pick --abort and --quit?

--abort goes back to before the whole cherry-pick, dropping any commits a range had already picked. --quit stops where you are and keeps those commits.

Can I cherry-pick again after aborting?

Yes. The original commit is still on its branch. Run the same git cherry-pick and Git will stop on the same conflict.

Summary

In this article, we watched git cherry-pick --abort cancel a pick of "Space out the header links" onto main, leaving main and HEAD on ada2e79 with nothing moved, and covered how it differs from --quit when you're picking a range.

Next steps

git cherry-pick --continue finishes the pick instead, once you've resolved the conflict. git cherry-pick A..B covers picking several commits at once.