Fix: git cherry-pick error: could not apply commit (conflict)
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 bugerror: 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 commitGit 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:
- Cherry-pick is
git applywith author metadata, NOT a small merge. It has no shared ancestor to anchor the patch. If the surrounding code drifted, the patch fails. Thegit cherry-pickdocumentation and thegit rererereference are the canonical sources. git statusafter the conflict shows which files need resolution. Open them, look for<<<<<<<markers, pick the right side (or merge both), thengit add <file>andgit cherry-pick --continue.- Cherry-picking a MERGE commit needs
-m 1. Merge commits have two parents;-m 1tells Git to diff against the mainline parent. Cherry-picking the individual commits inside the merge is usually cleaner. -X theirsand-X oursare 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.”- Enable
git rererefor teams that cherry-pick often.git config rerere.enabled trueremembers 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 statusafter 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 --abortand 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 theirsto “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 taggedhotfix. 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 situation | Recommended fix | Why |
|---|---|---|
| Conflict on real changes you understand | Fix 1: resolve manually | Standard path |
| Conflict too complex, want a different approach | Fix 2: abort and rethink (merge, format-patch) | Cherry-pick is the wrong tool |
| Commit depends on earlier commits | Fix 3: cherry-pick the range in order | Missing dependencies |
| Source commit is a merge commit | Fix 4: -m 1, or pick individual commits | Two-parent commits need direction |
| Stuck with unmerged files from earlier | Fix 5: resolve or --abort first | Cannot start while in conflict state |
| Have uncommitted local changes | Fix 6: stash or commit first | Same as merge / pull |
| Want auto-resolution heuristic | Fix 7: -X theirs or -X ours (cautiously) | Bulk resolution |
| Want to review before committing | Fix 8: --no-commit | Stage 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.jsOpen 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 --continueGit 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 --abortThis 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.patchPick 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 applyFix 3: Cherry-Pick Multiple Related Commits
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 cde3456Find 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.jsIf 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 commit3A 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 abc1234Usually -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 bcd2345Fix 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 --abortFix 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 popFix: commit your changes first:
git add .
git commit -m "WIP: save current work"
git cherry-pick abc1234Fix 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 abc1234Check 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 --continueCheck 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.
Solo developer based in Japan. Every solution is cross-referenced with official documentation and tested before publishing.
Was this article helpful?
Related Articles
Fix: DVC Not Working — Remote Push Errors, Pipeline DAG Issues, and Git Integration
How to fix DVC errors — dvc push authentication failed, dvc pull file missing, pipeline stage not reproducing, cache out of disk space, dvc add vs dvc stage, conflict with git LFS, and S3/GCS remote setup.
Fix: Git Hooks Not Running — Husky Not Working, pre-commit Skipped, or lint-staged Failing
How to fix Git hooks not executing — Husky v9 setup, hook file permissions, lint-staged configuration, pre-commit Python tool, lefthook, and bypassing hooks in CI.
Fix: Git Keeps Asking for Username and Password
How to fix Git repeatedly prompting for credentials — credential helper not configured, HTTPS vs SSH, expired tokens, macOS keychain issues, and setting up a Personal Access Token.
Fix: Undo git reset --hard and Recover Lost Commits
How to undo git reset --hard and recover lost commits using git reflog — step-by-step recovery for accidentally reset branches, lost work, and dropped stashes.