Skip to content

Fix: git cherry-pick error: could not apply commit (conflict)

FixDevs · (Updated: )

Part of:  Docker, DevOps & Infrastructure

Quick Answer

How to fix git cherry-pick conflict errors caused by diverged branches, overlapping changes, missing context, renamed files, and merge commits.

The Patch That Will Not Apply Cleanly

Personally, I think cherry-pick conflicts are one of the most informative failure modes in Git. The error tells you exactly what happened: the patch could not slot into the current code because the surrounding context drifted. The fix is editorial: review what diverged, decide whether to merge or rewrite. I learned to read the conflict markers before reaching for any flag. You run git cherry-pick and get:

error: could not apply abc1234... Fix login bug
hint: After resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' and run 'git cherry-pick --continue'.
hint: To skip this patch, run 'git cherry-pick --skip'.
hint: To abort and go back to the previous state, run 'git cherry-pick --abort'.

Or variations:

CONFLICT (content): Merge conflict in src/auth/login.js
error: could not apply abc1234... Fix login bug
error: cherry-pick is not possible because you have unmerged files.
error: your local changes would be overwritten by cherry-pick.
fatal: bad object abc1234: not a valid commit

Git tried to apply a commit from one branch to your current branch, but the changes conflict with your existing code. The file context has diverged enough that Git cannot automatically merge the changes.

Quick Reference Before You Dive In

If you arrived here from Google with a fresh conflict, the five facts that resolve roughly 90 percent of cases:

  1. Cherry-pick is git apply with author metadata, NOT a small merge. It has no shared ancestor to anchor the patch. If the surrounding code drifted, the patch fails. The git cherry-pick documentation and the git rerere reference are the canonical sources.
  2. git status after the conflict shows which files need resolution. Open them, look for <<<<<<< markers, pick the right side (or merge both), then git add <file> and git cherry-pick --continue.
  3. Cherry-picking a MERGE commit needs -m 1. Merge commits have two parents; -m 1 tells Git to diff against the mainline parent. Cherry-picking the individual commits inside the merge is usually cleaner.
  4. -X theirs and -X ours are dangerous shortcuts. They auto-resolve conflicting hunks by picking one side entirely. Use only when you genuinely know one side should win; never to “make the conflict go away.”
  5. Enable git rerere for teams that cherry-pick often. git config rerere.enabled true remembers your conflict resolutions and replays them on recurring conflicts.

The rest of this article walks through each cause in detail, plus the failure modes most other guides skip.

Why Cherry-Pick Drifts So Easily

git cherry-pick takes a commit from one branch and replays it on your current branch. It applies the diff of that commit to your working tree. If the code around the changed lines is different on your branch, Git cannot determine how to apply the patch and reports a conflict.

Common causes:

  • Diverged code. The file has been modified differently on both branches since the original commit.
  • Overlapping changes. Both branches modified the same lines.
  • Missing dependencies. The cherry-picked commit depends on earlier commits that are not on your branch.
  • File was renamed or moved. The file path changed on one of the branches.
  • Different formatting. Whitespace changes, code reformatting, or line ending differences.
  • Cherry-picking a merge commit. Merge commits require special handling.

The reason cherry-pick is more fragile than merge is that it has less context. A merge knows about the common ancestor of the two branches and can use that to reason about three-way diffs. Cherry-pick only has the diff of one commit and the current state of your branch; no shared ancestor to anchor the patch. When the surrounding code drifts even slightly (a renamed variable, a moved import block, a reformatted line), Git cannot find the right insertion point and reports a conflict.

The mental model that helps: think of cherry-pick as git apply with author metadata, not as a small merge. The patch either applies cleanly to the current file contents or it does not. Most “cherry-pick is hard” experiences come from cherry-picking commits that are too old, too far across the divergence, or that depend on changes that never made it to the target branch.

In Production: Incident Lens

Cherry-pick conflicts in production are almost always a hotfix scenario: a fix landed on the main development branch, the release branch is two weeks behind, and someone needs to ship that one fix without dragging in the other 50 commits. The conflict is the price of branch divergence; the way you resolve it determines whether the fix actually fixes the production problem or quietly drops half of itself.

  • How it surfaces: Not as a 5xx spike; this one shows up in your terminal during the incident response, not on a dashboard. The pattern is: incident declared, fix identified, fix commit found, git cherry-pick <sha> onto the release branch, conflict appears. The pressure is on; the temptation to resolve quickly is high; the risk of dropping part of the fix is highest exactly when it matters most.
  • Blast radius: Zero if you catch the conflict before pushing. Catastrophic if you resolve it wrong and the hotfix appears to be in the release but the actual behavior change is missing: the production incident continues, you assume the fix is deployed, you waste an hour investigating the wrong thing. The worst variant is a partial conflict resolution that compiles but does not fix the bug.
  • What catches it: git status after the cherry-pick is the obvious signal, but the meaningful one is the verification step after the deploy. A smoke test or canary that exercises the exact bug being fixed will tell you if the cherry-pick actually applied the fix. Without that test, the conflict resolution is unverified.
  • Recovery sequence: Three-step decision tree. (1) If the conflict touches more than the lines the fix intended to change, abort with git cherry-pick --abort and reconsider; the divergence is too large for a clean cherry-pick. (2) If the conflict is on adjacent context only, resolve manually with both versions visible, then run the test that exercises the fixed bug. (3) If you cannot find a safe resolution under time pressure, ship a forward-only fix written against the release branch directly. Do not blindly use -X theirs to “make it apply”; that strategy drops your local changes silently.
  • Postmortem preventive: Two durable controls. First, enable git rerere (git config rerere.enabled true) so resolutions to recurring conflicts are remembered and replayed. This is essential for teams that cherry-pick between long-lived branches regularly. Second, automate the “did the cherry-pick actually land?” check: a CI job on the release branch that runs the regression test for every recent fix tagged hotfix. The check fails if the regression returns, regardless of whether the commit appears in the log.

When to Use Which Fix

The next eight sections cover the fixes in detail. The table below maps your situation to the recommended fix.

Your situationRecommended fixWhy
Conflict on real changes you understandFix 1: resolve manuallyStandard path
Conflict too complex, want a different approachFix 2: abort and rethink (merge, format-patch)Cherry-pick is the wrong tool
Commit depends on earlier commitsFix 3: cherry-pick the range in orderMissing dependencies
Source commit is a merge commitFix 4: -m 1, or pick individual commitsTwo-parent commits need direction
Stuck with unmerged files from earlierFix 5: resolve or --abort firstCannot start while in conflict state
Have uncommitted local changesFix 6: stash or commit firstSame as merge / pull
Want auto-resolution heuristicFix 7: -X theirs or -X ours (cautiously)Bulk resolution
Want to review before committingFix 8: --no-commitStage but defer commit

If multiple rows apply, pick the topmost one.

Fix 1: Resolve the Conflict Manually

The standard approach. Open the conflicted files and resolve:

# See which files have conflicts
git status
# Both modified: src/auth/login.js

Open the file and find conflict markers:

<<<<<<< HEAD
// Your current branch's version
function login(email, password) {
  return authService.signIn(email, password);
}
=======
// The cherry-picked commit's version
function login(email, password) {
  const result = authService.signIn(email, password);
  logLoginAttempt(email);
  return result;
}
>>>>>>> abc1234 (Fix login bug)

Resolve by keeping the correct version:

// Combine both changes (usually what you want)
function login(email, password) {
  const result = authService.signIn(email, password);
  logLoginAttempt(email);
  return result;
}

Complete the cherry-pick:

git add src/auth/login.js
git cherry-pick --continue

Git opens your editor for the commit message. Save and close to complete the cherry-pick.

A discipline I have built: for any conflict that touches more than two or three lines, I open a visual merge tool with git mergetool. Reading conflict markers in a text editor is fine for one-line changes, but for anything more complex, a side-by-side diff view (VS Code, IntelliJ, Beyond Compare) shows the structure of both sides in a way that prose cannot. The extra 30 seconds to launch the tool has saved me from countless mis-resolutions.

Fix 2: Abort and Try a Different Approach

If the conflicts are too complex, abort and rethink:

git cherry-pick --abort

This restores your branch to the state before the cherry-pick attempt.

Alternatives to cherry-pick:

# Merge the entire branch instead
git merge feature-branch

# Rebase (if you want a linear history)
git rebase feature-branch

# Create a patch and apply manually
git format-patch -1 abc1234
git apply --3way 0001-Fix-login-bug.patch

Pick specific files instead of the whole commit:

# Get just one file from another branch
git checkout feature-branch -- src/auth/login.js

# Or show the diff and apply selectively
git diff abc1234^..abc1234 -- src/auth/login.js | git apply

If the commit depends on earlier commits, cherry-pick them in order:

# Cherry-pick a range of commits (oldest to newest)
git cherry-pick abc1234^..def5678

# Or cherry-pick multiple specific commits
git cherry-pick abc1234 bcd2345 cde3456

Find which commits the target depends on:

# See what files the commit changed
git show --stat abc1234

# See the full diff
git show abc1234

# Find commits that modified the same files
git log --oneline -- src/auth/login.js

If commits must be applied in order:

# List commits on the source branch since it diverged
git log --oneline main..feature-branch

# Cherry-pick from oldest to newest
git cherry-pick commit1 commit2 commit3

A common production cherry-pick mistake: picking only the “fix” commit when the fix depends on a refactor commit that came earlier. The cherry-pick applies but the code does not compile because a helper function the fix expects does not exist on the target branch. Always look at what the commit touches and verify those changes are already present, or pick the dependency commits too.

Fix 4: Fix Cherry-Picking Merge Commits

Merge commits have two parents. Git does not know which parent to diff against:

git cherry-pick abc1234
# error: commit abc1234 is a merge but no -m option was given.

Fix: specify the parent:

# -m 1 uses the first parent (usually the branch being merged into)
git cherry-pick -m 1 abc1234

# -m 2 uses the second parent (the branch being merged)
git cherry-pick -m 1 abc1234

Usually -m 1 is what you want. The first parent is the mainline branch, and the diff represents the changes introduced by the merge.

Better approach: cherry-pick the individual commits instead:

# Find the actual commits in the merged branch
git log --oneline abc1234^2..abc1234
# abc1234 Merge branch 'feature'
# bcd2345 Fix login bug
# cde3456 Add login logging

# Cherry-pick the individual commits
git cherry-pick cde3456 bcd2345

Fix 5: Fix Unmerged Files Error

If you have unresolved conflicts from a previous operation:

error: cherry-pick is not possible because you have unmerged files.

Resolve the existing conflicts first:

# See what's unresolved
git status

# Resolve conflicts in each file, then:
git add <resolved-files>

# If you were in the middle of a previous cherry-pick
git cherry-pick --continue

# Or abort everything and start fresh
git cherry-pick --abort

Fix 6: Fix Local Changes Error

If you have uncommitted changes:

error: your local changes would be overwritten by cherry-pick.

Fix: stash your changes:

git stash
git cherry-pick abc1234
git stash pop

Fix: commit your changes first:

git add .
git commit -m "WIP: save current work"
git cherry-pick abc1234

Fix 7: Use —strategy-option for Conflict Resolution

Automated conflict resolution strategies:

# Prefer the cherry-picked commit's version when there's a conflict
git cherry-pick -X theirs abc1234

# Prefer your current branch's version
git cherry-pick -X ours abc1234

# Ignore whitespace changes
git cherry-pick -X ignore-all-space abc1234

-X theirs automatically resolves conflicts by taking the cherry-picked commit’s version. Useful when you know the incoming changes should win.

-X ours keeps your current branch’s version. Useful when you only want non-conflicting parts of the cherry-picked commit.

Warning: These options only affect conflicting hunks. Non-conflicting changes from both sides are always included.

Fix 8: Cherry-Pick Without Committing

Apply the changes without creating a commit, so you can review and modify:

git cherry-pick --no-commit abc1234
# or
git cherry-pick -n abc1234

# Changes are staged but not committed
git status
git diff --cached

# Modify if needed
git checkout -- src/unwanted-file.js  # Undo specific files

# Commit when ready
git commit -m "Cherry-pick login fix from feature branch"

This gives you full control over what gets committed and the commit message.

Stranger Causes I Have Tracked Down

Check that the commit exists in your repo:

git cat-file -t abc1234
# Should output: commit
# If "fatal: bad object", the commit is not in your local repo

# Fetch from remote first
git fetch origin
git cherry-pick abc1234

Check for binary file conflicts. Binary files cannot be auto-merged:

# Accept the cherry-picked version
git checkout --theirs path/to/binary.png
git add path/to/binary.png
git cherry-pick --continue

Check for submodule conflicts. Submodule pointer changes can conflict and need manual resolution.

Check for line-ending and EOL conflicts. If the source branch was authored on Windows (CRLF) and the target branch on Linux (LF), every line of the diff can register as a conflict even when the actual content is identical. Run git config core.autocrlf input and re-normalize line endings with git add --renormalize . before attempting the cherry-pick.

Check for .gitattributes filter conflicts. Smudge/clean filters or LFS pointers can transform file contents between checkout and commit. A cherry-pick that touches an LFS-tracked binary may conflict on pointer files even when the underlying objects are unchanged. Run git lfs status to see what LFS thinks is in flight.

Verify the cherry-pick landed in the deploy. After resolving and pushing, confirm the commit is in the deployed artifact: git log --oneline release-branch | grep <sha>. Then verify behavior with a smoke test that targets the specific bug. A conflict resolution that compiles is not the same as a fix that works.

Check for git rerere replaying a stale resolution. If rerere is enabled, Git silently replays a remembered resolution. If that resolution was wrong on a previous occasion, it is silently wrong now too. Inspect with git rerere status and clear with git rerere clear if the replayed resolution looks suspicious.

What Other Tutorials Get Wrong About Cherry-Pick Conflicts

Most Git tutorials list the same fixes but frame them in ways that produce subtle bugs.

They recommend -X theirs as a “quick fix.” This silently drops your branch’s changes for any conflicting hunk. Articles that show it as a casual flag teach a pattern that silently corrupts production deploys.

They miss the merge-commit -m 1 requirement. Cherry-picking a merge commit without -m fails with a confusing error. Articles that show generic git cherry-pick <sha> examples leave readers stuck on merge commits.

They treat cherry-pick as a small merge. It is not; it is git apply with author metadata. Cherry-pick has no shared ancestor and is much more fragile than merge. Articles that conflate the two understate how often cherry-pick fails.

They omit git rerere. Teams that cherry-pick frequently (release branches, downstream forks) save hours with rerere. Articles that focus on one-shot cherry-picks miss this team-scale tool.

They miss the dependency-commits problem. A commit that uses a function added by a previous commit will not compile after cherry-pick if the previous commit was not also picked. Articles that show single-commit cherry-pick examples miss this gotcha.

They miss the verification step. A successful cherry-pick --continue is not proof the fix landed correctly. The smoke test for the specific bug being fixed is the only definitive signal. Articles that treat cherry-pick as the last step miss the verification half.

Frequently Asked Questions

Why does cherry-pick conflict when merge would not?

Cherry-pick has less context than merge. A merge knows about the common ancestor of the two branches and uses three-way diff. Cherry-pick only has the diff of one commit and the current state. When surrounding code drifts (renamed variables, moved imports, reformatted lines), cherry-pick cannot find the right insertion point even when merge would succeed.

What does -m 1 do?

It tells git cherry-pick which parent of a merge commit to diff against. Merge commits have two parents; -m 1 uses the first (the mainline branch). -m 2 uses the second (the merged-in branch). Usually -m 1 is correct.

Should I use -X theirs to make conflicts go away?

Almost never. It silently drops your local changes for any conflicting hunk. The conflict is Git telling you the patch does not slot in cleanly; auto-resolving it picks one side without your review. Use only when you genuinely know one side should win for every conflict in the patch.

Is git rerere worth enabling?

For teams that cherry-pick or rebase regularly, yes. git config rerere.enabled true makes Git remember your conflict resolutions and replay them automatically on recurring conflicts. The first conflict resolution becomes effort saved on every subsequent re-encounter.

Why does my cherry-pick succeed but the fix doesn’t work?

Either the conflict resolution dropped part of the fix, or the commit depended on earlier commits that you didn’t pick. Always verify with a test that exercises the specific bug. A green build is not the same as a working fix.

Can I cherry-pick a range of commits?

Yes: git cherry-pick A..B picks every commit from A (exclusive) to B (inclusive). Use A^..B to include A as well. The commits are applied in order; if any conflict, Git pauses and you resolve before continuing.

For general merge conflicts, see Fix: Git merge conflict. For rebase conflicts, see Fix: Git rebase conflict. For stash conflicts, see Fix: Git stash pop conflict. If your push is rejected after pushing the cherry-pick, see Fix: Git push rejected non-fast-forward.

F

FixDevs

Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.

Was this article helpful?

Related Articles