# Fix Git Cherry-Pick Range Applied in Wrong Order

You cherry-pick a range of commits:

bash
git cherry-pick A..B

And the resulting code is broken. The commits were applied in the wrong order, or some commits were skipped entirely. The final state does not match what you expected.

Understanding Cherry-Pick Range Syntax

The A..B range notation means "all commits reachable from B but not from A":

bash
# Commits from feature branch not in main
git cherry-pick main..feature

This cherry-picks all commits on feature that are not on main, in chronological order (oldest first).

The A^..B notation includes commit A itself:

bash
# Include commit A in the range
git cherry-pick A^..B

The Common Mistake: Wrong Range Direction

```bash # WRONG: This cherry-picks commits reachable from main but not from feature # (probably nothing or the wrong commits) git cherry-pick feature..main

# CORRECT: Cherry-pick commits from feature that are not on main git cherry-pick main..feature ```

Always think: "from which branch am I taking commits?" That branch goes on the RIGHT side of ...

Step 1: Preview the Cherry-Pick Range

Before executing, verify the commits that will be picked:

bash
git log --oneline main..feature

This shows exactly which commits will be cherry-picked and in what order. If the list looks wrong, fix the range.

Step 2: Abort a Bad Cherry-Pick

If the cherry-pick goes wrong mid-range:

bash
git cherry-pick --abort

This restores the state before the cherry-pick started. All commits picked so far are reverted.

Step 3: Cherry-Pick Specific Commits

Instead of a range, cherry-pick specific commits in the correct order:

bash
git cherry-pick abc1234 def5678 901abcd

This applies exactly these three commits in the order specified. You control the order, not Git.

Step 4: Cherry-Pick in Reverse Order

If commits must be applied in reverse order (rare, but happens with dependency chains):

bash
# Get the commits in reverse order
git log --oneline --reverse main..feature | tac | awk '{print $1}' | xargs git cherry-pick

Or manually:

bash
git cherry-pick 901abcd def5678 abc1234

Step 5: Merge Conflicts in Cherry-Pick Range

When cherry-picking a range, each commit is applied individually. If one commit causes a conflict, the cherry-pick pauses:

bash
error: could not apply def5678... Add new feature
hint: After resolving the conflicts, mark them with
hint: "git add/rm <pathspec>", then run
hint: "git cherry-pick --continue".
hint: You can instead skip this commit with "git cherry-pick --skip".
hint: To abort and get back to the state before "git cherry-pick",
hint: run "git cherry-pick --abort".

Resolve the conflict:

bash
git add resolved_file.txt
git cherry-pick --continue

Or skip the problematic commit:

bash
git cherry-pick --skip

Step 6: Cherry-Pick With Edit

To modify the commit message during cherry-pick:

bash
git cherry-pick -e abc1234

This opens the editor with the commit message, allowing you to modify it before the commit is created.

Step 7: Cherry-Pick Without Commit

To stage changes without immediately committing:

bash
git cherry-pick --no-commit abc1234 def5678

This stages all changes from the specified commits but does not create individual commits. You can then combine them into a single commit:

bash
git commit -m "Combined feature from multiple commits"

Step 8: Verify Cherry-Pick Result

After cherry-picking, verify the result:

```bash # Check that all expected commits were applied git log --oneline -10

# Compare with the source branch git diff main..HEAD --stat ```

The diff should be empty (or show only the cherry-picked changes). If there are unexpected differences, a commit was missed or applied incorrectly.

Best Practice: Cherry-Pick From Feature Branches

Cherry-pick works best when: - Cherry-picking FROM a well-tested feature branch TO a release branch - The commits are self-contained and do not depend on other un-picked commits - The target branch has not diverged too far from the source

Avoid cherry-picking: - Individual commits from a complex refactoring (use merge instead) - Commits that depend on other commits not in the range - Commits that modify the same files as recent changes on the target branch