Kokil Thapa - Professional Web Developer in Nepal
Freelancer Web Developer in Nepal with 15+ Years of Experience

Kokil Thapa is an experienced full-stack web developer focused on building fast, secure, and scalable web applications. He helps businesses and individuals create SEO-friendly, user-focused digital platforms designed for long-term growth.

Git Cherry-Pick Explained

By Kokil Thapa | Last reviewed: September 2026

You need one bug fix on production, but the branch holds twenty unfinished features. Git cherry-pick explained properly means copying a single commit onto another branch without dragging the rest of the history along. On real client projects I maintain with GitFlow-style release branches, cherry-pick is how we move a validated patch from develop to main at 11 p.m. without a risky full merge. This guide covers the commands, conflict workflow, and the mistakes that duplicate commits or lose authorship.

What does Git cherry-pick do and when should you use it?

Cherry-pick takes an existing commit and replays it on your current branch. Git does not move the original commit. It creates a new commit with the same patch and usually the same message. The new commit gets a different hash because its parent differs.

Reach for cherry-pick when the change is small and isolated. Hotfixes, security patches, and backports to an older release line are the classic cases. I use it regularly on production maintenance work where downtime must stay minimal.

Skip cherry-pick when you need an entire feature branch. A merge or rebase preserves relationship between commits. Cherry-picking ten related commits one by one is painful and error-prone. If two commits depend on each other, pick them in chronological order or merge the branch instead.

Git Cherry-Pick: One Commit, New BranchfeatureABCFix bug (C)mainAC'Same patchgit cherry-pick CNew hash, same diff as commit C
Git cherry-pick explained: commit C from feature is replayed as C prime on main without commits A and B.

Common scenarios that fit cherry-pick

  • Production hotfix: Fix lands on develop first. Cherry-pick it onto main for immediate deploy.
  • Release backport: Patch a bug in v2.4 while v2.5 is already in progress on another branch.
  • Revert a revert: Someone reverted your fix by mistake. Cherry-pick the original fix commit again.
  • CI rescue: A good commit sits on a discarded branch. Recover it with reflog lookup plus cherry-pick.

How do you cherry-pick a commit step by step?

The workflow is short. Find the commit hash, switch to the target branch, run cherry-pick, then push. The details matter when conflicts appear or when you pick multiple commits.

Step 1: Identify the commit hash

Use git log on the source branch. Copy the full SHA or the short form Git prints.

git checkout feature/payment-fix
git log --oneline -5

# Example output:
# a1b2c3d Fix Khalti callback timeout handling
# e4f5g6h Add cart validation rules
# i7j8k9l Refactor checkout controller

You want a1b2c3d in this example. The one-line log keeps the hash visible without scrolling.

Step 2: Switch to the target branch and cherry-pick

git checkout main
git pull origin main
git cherry-pick a1b2c3d

Git applies the diff from that commit onto your current HEAD. If nothing conflicts, you get a new commit instantly. Git opens your editor for the commit message unless you pass -n or --no-commit.

Step 3: Cherry-pick a range of commits

Sometimes you need three related commits, not one. Use the range syntax. The start commit is excluded; the end commit is included.

git cherry-pick e4f5g6h..a1b2c3d

That replays everything after e4f5g6h up to and including a1b2c3d. Order matters. Git applies them oldest-first.

Step 4: Push and verify

git push origin main
git log --oneline -3

Run your test suite before push on production branches. Cherry-pick does not run CI for you. On projects using Git hooks, the pre-push hook still fires.

Cherry-Pick Workflowgit logFind hashcheckoutTarget branchcherry-pickApply patchConflict?Resolve or skipNo conflictAuto commit createdConflictEdit, add, continuegit push origin branchDeploy via CI or Deployer
Step-by-step Git cherry-pick workflow from finding the commit hash through conflict resolution to push.

How do you resolve Git cherry-pick conflicts?

Conflicts happen when the target branch changed the same lines since the original commit was written. Cherry-pick conflicts look like merge conflicts. Git pauses and marks conflicted files.

When cherry-pick stops, run git status. Open each conflicted file. You will see the standard conflict markers. Fix the code. Stage the file. Continue the operation.

git status
# both modified: app/Http/Controllers/PaymentController.php

# Edit the file, remove <<<<<<< markers, keep correct code

git add app/Http/Controllers/PaymentController.php
git cherry-pick --continue

If the conflict is too messy, abort and try a different approach. git cherry-pick --abort returns your branch to its pre-cherry-pick state. That is safer than leaving a half-applied patch.

Useful flags during conflict recovery

CommandWhat it doesWhen to use it
git cherry-pick --continueComplete after resolving conflictsAfter git add on all fixed files
git cherry-pick --abortCancel and restore pre-pick stateConflict too complex; choose merge instead
git cherry-pick --skipDrop current commit, move to next in rangeOne commit in a range is unwanted
git cherry-pick -xAppend source commit hash to messageAudit trail on release branches
git cherry-pick -nApply changes without committingSquash multiple picks into one commit

The -x flag is underrated on long-lived products. It appends a line like (cherry picked from commit a1b2c3d) to the message. Six months later you know exactly where the patch originated. See the official git-cherry-pick documentation for the full flag list.

For deeper conflict mechanics, read our guide on resolving Git merge conflicts. The same diff3 thinking applies.

What is the difference between cherry-pick, merge, and rebase?

All three integrate changes across branches. They differ in history shape and scope. Pick the tool that matches how much history you need to move.

MethodScopeHistoryBest for
Cherry-pickOne or a few commitsLinear; new commits on targetHotfixes, isolated backports
MergeEntire branch tipMerge commit joins two linesFeature completion, shared branches
RebaseReplay commit seriesLinear; rewrites commit hashesCleaning feature branch before merge

Cherry-pick is surgical. Merge is wholesale. Rebase reshapes a whole branch line. On a production Laravel app I maintain, we cherry-pick onto main for urgent fixes. We merge feature branches into develop for normal work. We rebase feature branches locally before opening a merge request.

Compare further in Git rebase vs merge when you need a longer decision framework.

Cherry-Pick vs Merge vs RebaseCherry-Pick1 commit copiedHotfix to mainKeeps branches apartMergeWhole branch joinedFeature completeMerge commit nodeRebaseReplay all commitsLinear historyRewrites SHAsDecision ruleOne fix, two branches? Cherry-pick.Whole feature ready? Merge.Clean up before MR? Rebase locally.
Git cherry-pick explained alongside merge and rebase: choose based on how many commits and how much history you need.

What are common Git cherry-pick mistakes and how do you avoid them?

Cherry-pick looks simple until production proves otherwise. These failures show up repeatedly on teams I work with.

Duplicate commits after a later merge

You cherry-pick commit C onto main. Later you merge feature into main. Git may apply C's changes again or create a confusing merge. The patch content is identical, but the commit objects differ.

Git usually detects duplicate patches and skips them during merge. Do not rely on that silently. After cherry-picking a fix to main, note the hash in your ticket. When the feature branch merges, watch for conflicts in the same files.

Cherry-picking merge commits

A merge commit has two parents. Plain git cherry-pick on a merge commit fails or behaves unexpectedly. Use -m 1 to specify the mainline parent.

git cherry-pick -m 1 <merge-commit-hash>

Parent 1 is typically the branch you merged into. Parent 2 is the feature side. Pick the wrong parent and you apply the inverse of what you expect. Read the mainline parent docs before using this on shared branches.

Losing track on shared release branches

Three developers cherry-pick the same fix to three release branches without coordination. Each gets a different hash. Bug trackers reference different SHAs. Use -x and a shared changelog. On sister sites I deploy with Deployer 7, we log cherry-picked hashes in the release notes file.

Cherry-picking secrets or generated files

A commit might accidentally include a .env snippet or a compiled asset. Cherry-pick copies that too. Run secrets scanning in CI before merge requests land. Never cherry-pick commits that touch credentials without review.

Duplicate Patch GotchaTimeline on mainAC'Cherry-picked fixMFeature mergeRiskSame code, two commitsC prime and C from featureMerge may conflict or skipPrevention checklistUse cherry-pick -x for traceabilityLog hash in ticket before feature mergeRun tests after pick and after merge
Common Git cherry-pick mistake: duplicate patches when the source feature branch merges later into the same target.

How do you undo a Git cherry-pick?

If the cherry-pick has not been pushed, reset is clean. If it is already on the remote, revert instead.

Before push: reset to previous commit

git reset --hard HEAD~1

That drops the cherry-picked commit locally. Use HEAD~1 only when the cherry-pick was your last action. Verify with git log -1 first.

After push: revert the cherry-pick commit

git revert <cherry-picked-commit-hash>
git push origin main

Revert creates a new commit that undoes the patch. Shared branches stay safe. Force-pushing after a bad cherry-pick breaks teammates' clones. Avoid git push --force on main unless your team policy explicitly allows it.

The Pro Git book chapter on rewriting history covers reset vs revert in more depth.

How does cherry-pick fit a real production hotfix workflow?

Theory is easy. Production adds constraints: CI gates, zero-downtime deploys, and two active release lines. Here is a workflow I use on Laravel projects with GitLab CI and Deployer 7.

  1. Reproduce the bug on main. Confirm it is fixed on develop in commit a1b2c3d.
  2. Create a hotfix branch from main: git checkout -b hotfix/payment-callback main.
  3. Cherry-pick with traceability: git cherry-pick -x a1b2c3d.
  4. Run PHPUnit and static analysis locally. Push and open a merge request to main.
  5. After CI passes, merge and deploy. Tag the release: git tag v1.4.1.
  6. Cherry-pick the same commit to any older supported branch if clients still run it.

On the Adventure Third Pole Trek booking platform, this pattern ships payment fixes without waiting for unrelated Livewire UI work on develop. The deploy pipeline reloads PHP-FPM after symlink swap, same as any normal release.

For enterprise apps with stricter gates, pair cherry-pick with CI code review checks and branch protection. Azure DevOps and GitHub both support required reviews on hotfix branches.

If your team manages server config in Git, see dotfiles and server config with Git for keeping environment parity across staging and production.

Cherry-pick with empty commits

Sometimes Git says the cherry-pick is empty. The patch already exists on the target branch. Git offers to skip or continue. Usually you skip. An empty commit adds noise to history.

git cherry-pick a1b2c3d
# On branch main
# You are currently cherry-picking commit a1b2c3d.
# The previous cherry-pick is now empty, possibly due to conflict resolution.
git cherry-pick --skip

Key Takeaways

  • git cherry-pick <hash> replays one commit's diff onto your current branch as a new commit with a new SHA.
  • Use cherry-pick for isolated hotfixes and backports; merge or rebase when you need an entire feature branch.
  • On conflicts: fix files, git add, then git cherry-pick --continue; use --abort if the patch no longer applies cleanly.
  • Always add -x on shared release branches so the source commit hash stays in the message.
  • After pushing a bad pick, use git revert instead of force-pushing shared branches.
  • Watch for duplicate patches when the source branch eventually merges into the same target.

People Also Ask

Can you cherry-pick multiple commits at once?

Yes. Pass a range: git cherry-pick start..end excludes start and includes end. You can also list hashes: git cherry-pick hash1 hash2 hash3. Git applies them in order. If one fails, resolve or abort before the rest continue.

Does cherry-pick change the original commit?

No. The source branch and commit stay untouched. Cherry-pick only creates new commits on the branch where you run the command. Think of it as copy-paste for patches, not cut-paste.

What is the difference between git cherry-pick and git revert?

Cherry-pick applies a past commit's changes forward onto your branch. Revert creates a new commit that undoes a previous commit's changes. They solve opposite problems. Pick brings a fix in; revert rolls a bad change out.

Is cherry-pick safe on public shared branches?

Yes, when the picked commit is already reviewed and tested. Cherry-pick does not rewrite published history the way rebase-and-force-push does. It appends a normal commit. Still run CI and code review on hotfix branches before merging to main.

Ship hotfixes without merging half-finished work

Git cherry-pick explained boils down to surgical history editing. You copy one validated commit onto production while feature work stays on its own branch. Master the basic command, the conflict flags, and the duplicate-patch trap. Your deploys get faster and your release branches stay readable.

If your team needs help tightening Git workflows, CI pipelines, or zero-downtime Laravel deploys, see our Linux system administration and enterprise application development services. For a quick JSON payload check during API hotfixes, use the free JSON formatter. Ready to audit your deployment process? Contact us and we will map a workflow that fits your stack.

Frequently Asked Questions

Git cherry-pick replays an existing commit's diff onto your current branch as a new commit with a different hash; the original commit stays on its source branch.

Use cherry-pick for small, isolated changes: production hotfixes, security patches, and backports to older release lines. Skip it when you need an entire feature branch or many dependent commits—merge preserves full branch history, and rebase reshapes a whole line. On Laravel projects I maintain with GitFlow-style release branches, we cherry-pick validated patches from develop onto main at night without dragging twenty unfinished features along.

Find the commit hash with git log on the source branch, switch to your target branch, pull latest, then run git cherry-pick followed by the hash. If nothing conflicts, Git creates a new commit instantly. Run your test suite before pushing to production branches—cherry-pick does not run CI for you, though pre-push hooks still fire. For multiple related commits, use range syntax where the start commit is excluded and the end commit is included. Git applies them oldest-first.

Conflicts happen when the target branch changed the same lines since the original commit was written. Git pauses and marks conflicted files, just like a merge conflict. Run git status, open each conflicted file, remove the conflict markers, and keep the correct code. Stage fixed files with git add, then run git cherry-pick --continue. If the conflict is too messy, git cherry-pick --abort returns your branch to its pre-cherry-pick state. That is safer than leaving a half-applied patch on a shared branch.

Cherry-pick copies one or a few commits onto another branch as new commits with linear history—best for hotfixes and isolated backports. Merge joins an entire branch tip with a merge commit, preserving both histories—best for feature completion on shared branches. Rebase replays a whole commit series onto a new base, rewriting hashes—best for cleaning a feature branch before merge. On production Laravel apps I maintain, cherry-pick handles urgent main fixes, merge handles normal develop integration, and rebase tidies branches locally.

Yes. Pass a range with git cherry-pick start..end—the start commit is excluded, the end is included. You can also list individual hashes separated by spaces. Git applies them in chronological order, oldest first. If one commit in the range is unwanted or fails, use git cherry-pick --skip to drop it and move to the next. When a commit in the middle conflicts, resolve it and continue, or abort the entire operation if the patch no longer applies cleanly to the target branch.

No. The source branch and original commit remain untouched. Cherry-pick only creates new commits on the branch where you run the command—it copies the patch, not the commit object.

Cherry-pick applies a past commit's changes forward onto your current branch, bringing a fix or patch in. Revert creates a new commit that undoes a previous commit's changes, rolling a bad change out. They solve opposite problems. After pushing a bad cherry-pick to a shared branch like main, use git revert on the cherry-picked commit hash rather than git push --force, which breaks teammates' clones. Revert keeps shared branch history safe for everyone working from the same remote.

Three failures show up repeatedly on teams I work with. First, duplicate patches when the source feature branch later merges into the same target—note cherry-picked hashes in your ticket. Second, cherry-picking merge commits without -m 1 to specify the mainline parent, which applies the wrong diff. Third, picking commits that accidentally include .env snippets or credentials without review. Use the -x flag and a shared changelog on release branches. On sister sites deployed with Deployer 7, we log cherry-picked hashes in release notes.

If you have not pushed yet, verify with git log -1 that the cherry-pick was your last action, then run git reset --hard HEAD~1 to drop it locally. Once the pick is on the remote, use git revert followed by the cherry-picked commit hash, then push normally. Revert adds a new commit that undoes the patch without rewriting shared history. Avoid git push --force on main unless your team policy explicitly allows it—force-pushing after a bad cherry-pick breaks teammates' clones.

The -x flag appends the source commit hash to the new commit message, adding a line like cherry picked from commit a1b2c3d. On long-lived products and shared release branches, that audit trail matters—six months later you know exactly which upstream commit the patch came from. Without it, three developers cherry-picking the same fix to three release branches each get a different hash, and bug trackers reference different SHAs for the same change. I consider -x underrated on any branch that outlives a single sprint.

A merge commit has two parents, so plain git cherry-pick on it fails or behaves unexpectedly. Use git cherry-pick -m 1 followed by the merge commit hash. Parent 1 is typically the branch you merged into; parent 2 is the feature side. Picking the wrong parent applies the inverse of what you expect. Read the mainline parent documentation before using this on shared branches where the history graph is not obvious from a quick git log --oneline view.

Git reports an empty cherry-pick when the patch already exists on the target branch, often because someone applied the same fix earlier or conflict resolution removed all differences. Usually you should skip rather than continue—an empty commit adds noise to history with no actual code change. Run git cherry-pick --skip to move on to the next commit in a range or to exit the operation cleanly. This is common when backporting a fix that was already merged into the target through another path.

Reproduce the bug on main, confirm the fix exists on develop, create a hotfix branch from main, and cherry-pick with -x for traceability. Run PHPUnit and static analysis locally, push, and open a merge request. After GitLab CI passes, merge, deploy with Deployer 7, and tag the release. Cherry-pick the same commit to any older supported branches still in production. On the Adventure Third Pole Trek booking platform, this ships payment fixes without waiting for unrelated Livewire UI work sitting on develop.

Yes, when the commit is reviewed and tested. Cherry-pick appends a normal commit without rewriting published history like force-pushed rebase. Still run CI and code review before merging to main.

Share this article

0 Comments

Leave a comment

Your email is not published. Comments appear once they have been read. Sign in to have your details filled in.

Quick Contact Options
Choose how you want to connect me: