|$ curl https://forge-ai.dev/api/markdown?path=docs/git/cherry-pick
$cat docs/git-cherry-pick.md
updated Recently·18 min read·published
Git Cherry-pick
Introduction
git cherry-pick applies a specific commit from one branch to another without merging the entire branch. It creates a new commit with the same changes, useful for backporting fixes, recovering lost work, or selectively applying changes.
Basic Cherry-pick
cherry-pick-basic.sh
Bash
| 1 | # Cherry-pick a single commit |
| 2 | git cherry-pick abc1234 |
| 3 | |
| 4 | # Cherry-pick without committing (stage changes only) |
| 5 | git cherry-pick --no-commit abc1234 |
| 6 | # Review changes, then commit manually |
| 7 | git commit -m "Backport: fix login validation" |
| 8 | |
| 9 | # Cherry-pick with a custom commit message |
| 10 | git cherry-pick -m 1 -M "Backport fix to v1.x branch" abc1234 |
| 11 | |
| 12 | # Cherry-pick from a remote branch |
| 13 | git fetch origin |
| 14 | git cherry-pick origin/feature-branch~3 # 3 commits back from tip |
| 15 | |
| 16 | # View the commit before cherry-picking |
| 17 | git show abc1234 |
ℹ
info
Use --no-commit to stage changes without creating a commit. This lets you review the diff, make adjustments, and commit with a custom message.
Cherry-pick Ranges
cherry-pick-ranges.sh
Bash
| 1 | # Cherry-pick a range of commits (exclusive of start) |
| 2 | git cherry-pick abc1234..def5678 |
| 3 | # Applies commits after abc1234 up to and including def5678 |
| 4 | |
| 5 | # Cherry-pick inclusive range (use ^ to include the start) |
| 6 | git cherry-pick abc1234^..def5678 |
| 7 | # Includes abc1234 through def5678 |
| 8 | |
| 9 | # Cherry-pick multiple non-contiguous commits |
| 10 | git cherry-pick abc1234 def5678 ghi9012 |
| 11 | |
| 12 | # Cherry-pick last N commits from a branch |
| 13 | git cherry-pick main~3..main |
| 14 | |
| 15 | # Cherry-pick with merge commit preservation |
| 16 | git cherry-pick -m 1 abc1234 |
| 17 | # -m 1 keeps the parent side of the merge (usually main) |
| 18 | # -m 2 keeps the merged branch side |
Conflict Resolution
Cherry-pick conflicts are similar to merge conflicts. Git pauses and asks you to resolve them before continuing.
cherry-pick-conflicts.sh
Bash
| 1 | # Cherry-pick with conflicts |
| 2 | git cherry-pick abc1234 |
| 3 | # CONFLICT (content): Merge conflict in src/auth.ts |
| 4 | |
| 5 | # Resolve conflicts |
| 6 | # 1. Edit the conflicting files |
| 7 | # 2. Stage the resolved files |
| 8 | git add src/auth.ts |
| 9 | |
| 10 | # Continue cherry-picking |
| 11 | git cherry-pick --continue |
| 12 | |
| 13 | # Or abort and start over |
| 14 | git cherry-pick --abort |
| 15 | |
| 16 | # Skip a problematic commit (in a range) |
| 17 | git cherry-pick --skip |
| 18 | |
| 19 | # Useful during large range cherry-picks |
| 20 | git cherry-pick abc1234..xyz9999 |
| 21 | # If one commit conflicts: |
| 22 | git cherry-pick --skip # Skip the bad one, continue |
| 23 | |
| 24 | # View cherry-pick state |
| 25 | git status |
⚠
warning
Cherry-pick conflicts can be tricky because the commit was originally written against different surrounding code. Take time to understand the original intent, not just the diff.
Common Use Cases
use-cases.sh
Bash
| 1 | # 1. Backport a bugfix to a release branch |
| 2 | git checkout release/1.x |
| 3 | git cherry-pick abc1234 # The fix from main |
| 4 | |
| 5 | # 2. Recover a commit that was accidentally reverted |
| 6 | git cherry-pick abc1234 # The reverted commit |
| 7 | |
| 8 | # 3. Apply a fix from open source to your fork |
| 9 | git remote add upstream https://github.com/original/repo.git |
| 10 | git fetch upstream |
| 11 | git cherry-pick upstream/abc1234 |
| 12 | |
| 13 | # 4. Move a commit between branches (rebase alternative) |
| 14 | git checkout feature-v2 |
| 15 | git cherry-pick main~1 # Grab the latest commit from main |
| 16 | |
| 17 | # 5. Cherry-pick with sign-off (DCO compliance) |
| 18 | git cherry-pick -s abc1234 |
| 19 | # Adds Signed-off-by: Your Name <email> to commit message |
✓
best practice
Use cherry-pick sparingly. Frequent cherry-picking suggests your branching strategy needs adjustment. If you regularly backport to multiple release branches, consider a release-flow workflow or automated backport scripts.
Advanced Patterns
Extra depth for production teams — conflict strategies, automation, and recovery.
Automation-friendly flags
automation.sh
Bash
| 1 | git status --porcelain=v1 |
| 2 | git diff --name-only --diff-filter=ACMR |
| 3 | git log -1 --pretty=format:%H |
| 4 | git merge-base HEAD origin/main |
| 5 | git rev-list --count origin/main..HEAD |
Recovery drill
recovery.sh
Bash
| 1 | git reflog | head -20 |
| 2 | git fsck --lost-found | head |
| 3 | git branch rescue HEAD@{1} |
| 4 | git log --oneline rescue -5 |
🔥
pro tip
Practice recovery in /tmp labs before you need it on a deadline.
Production Checklist
- No secrets in history for this change set
- CI green on the PR
- Rebased or merged with latest main
- Rollback plan: revert SHA known
- Tags/releases updated if needed
prod-check.sh
Bash
| 1 | git status -sb |
| 2 | git log --oneline origin/main..HEAD |
| 3 | git diff --check |
| 4 | git rev-parse HEAD |
Additional Examples
more-a.sh
Bash
| 1 | # Cherry-pick a range onto a release branch |
| 2 | git switch release/1.2 |
| 3 | git cherry-pick abc123^..def456 |
| 4 | # conflict? |
| 5 | git status |
| 6 | # fix, then: |
| 7 | git add -A && git cherry-pick --continue |
| 8 | # or abort: |
| 9 | # git cherry-pick --abort |
more-b.sh
Bash
| 1 | # Bisect with a script |
| 2 | git bisect start |
| 3 | git bisect bad HEAD |
| 4 | git bisect good v1.0.0 |
| 5 | git bisect run ./scripts/test-bug.sh |
| 6 | git bisect reset |
more-c.sh
Bash
| 1 | # Submodule bump |
| 2 | git submodule update --remote --merge libs/shared |
| 3 | git add libs/shared |
| 4 | git commit -m "chore(deps): bump shared submodule" |
| 5 | git submodule status |
more-d.sh
Bash
| 1 | # Workflow: trunk-based short PR |
| 2 | git fetch origin |
| 3 | git switch -c fix/timeout origin/main |
| 4 | # change + test |
| 5 | git commit -am "fix: request timeout" |
| 6 | git push -u origin HEAD |
| 7 | gh pr create --fill |
| 8 | gh pr checks |
| 9 | gh pr merge --squash --delete-branch |
Cherry-pick Conflict & Sequencing Deep Dive
Cherry-pick applies the diff of a commit onto HEAD. When multiple commits are picked, order matters — apply oldest first unless you intentionally reverse.
Sequencing
cp-seq.sh
Bash
| 1 | # Oldest first |
| 2 | git cherry-pick abc111 def222 ghi333 |
| 3 | # Empty commit when change already present: |
| 4 | git cherry-pick --skip |
| 5 | # Keep original author when picking: |
| 6 | git cherry-pick --keep-redundant-commits abc111 |
Conflict resolution
cp-conflict.sh
Bash
| 1 | git cherry-pick abc123 |
| 2 | # CONFLICT |
| 3 | git status |
| 4 | git diff |
| 5 | # edit files, remove markers |
| 6 | git add -A |
| 7 | git cherry-pick --continue |
| 8 | # give up: |
| 9 | git cherry-pick --abort |
Backport recipe
cp-backport.sh
Bash
| 1 | git fetch origin |
| 2 | git switch -c backport/fix-timeout origin/release/1.2 |
| 3 | git cherry-pick <sha-from-main> |
| 4 | git push -u origin HEAD |
| 5 | gh pr create --base release/1.2 --fill |
✓
best practice
If you cherry-pick often, your branching strategy may need release branches or automated backports.
Vs rebase vs merge
- cherry-pick: copy select commits onto another line
- rebase: replay your whole branch onto a new base
- merge: join histories with a merge commit
cp-lab.sh
Bash
| 1 | rm -rf /tmp/cp-lab && mkdir /tmp/cp-lab && cd /tmp/cp-lab |
| 2 | git init -b main |
| 3 | echo a > f && git add f && git commit -m a |
| 4 | git switch -c topic |
| 5 | echo b > f && git commit -am b |
| 6 | echo c > f && git commit -am c |
| 7 | git switch main |
| 8 | git cherry-pick topic~1 # pick middle commit 'b' |
| 9 | cat f && git log --oneline |
Agent Notes — Cherry-pick
- Prefer explicit SHAs from git log --oneline
- Always state target branch before picking
- On conflict, never leave markers; prefer --abort if unsure
- Do not cherry-pick merge commits without -m
$Blueprint — Engineering Documentation·Section ID: GIT-CP-01·Revision: 1.0
Community
Get help on Slack, Discord or VIP
Stuck on a guide? Join the community and ask.