Skip to main content

Cherry-Pick & Bisect

Quick Summary

git cherry-pick copies a specific commit from one branch to another — like picking one cherry from the tree without taking the whole branch. git bisect performs a binary search through your commit history to find exactly which commit introduced a bug.


git cherry-pick

When to Use

  • Apply a hotfix from main to a release branch
  • Port a single commit without merging an entire branch
  • Recover a commit from a deleted branch

Syntax

# Cherry-pick a single commit
git cherry-pick <commit-hash>

# Cherry-pick multiple commits
git cherry-pick <hash1> <hash2> <hash3>

# Cherry-pick a range (exclusive of first commit)
git cherry-pick A..B

# Cherry-pick without committing (stage only)
git cherry-pick --no-commit <hash>

# Abort a cherry-pick in progress
git cherry-pick --abort

Example

# You're on main, and need a specific fix from feature branch
git log --oneline feature/auth
# d4e5f6a feat: add auth validation (← this one!)
# c3d4e5f feat: add auth UI
# b2c3d4e feat: add auth models

git checkout main
git cherry-pick d4e5f6a
[main e5f6a7b] feat: add auth validation
1 file changed, 15 insertions(+)
Cherry-pick creates a NEW commit

The cherry-picked commit gets a new SHA hash on the target branch. If you later merge the source branch, Git may flag the duplicate change.


git bisect

The Problem

Your app worked last week but is broken now. You have 50 commits since then. Which commit broke it?

Without bisect: Test each commit manually (50 checks)
With bisect: Binary search (6 checks for 50 commits)

How It Works

flowchart LR
C1["C1 ✅"] --> C2["C2"] --> C3["C3"] --> C4["C4"] --> C5["C5 🐛"] --> C6["C6"] --> C7["C7 ❌"]

style C1 fill:#4CAF50
style C5 fill:#f44336
style C7 fill:#f44336
# 1. Start bisect
git bisect start

# 2. Mark current commit as bad
git bisect bad

# 3. Mark a known good commit
git bisect good v1.0 # or a specific commit hash

# Git checks out the middle commit
# Bisecting: 25 revisions left to test (roughly 5 steps)
# 4. Test the code, then tell Git the result
git bisect good # This commit works → bug is in later commits
# or
git bisect bad # This commit is broken → bug is in earlier commits

# 5. Git narrows down and checks out the next middle commit
# Repeat step 4 until Git finds the exact commit

# 6. Git reports the first bad commit
# b2c3d4e is the first bad commit
# commit b2c3d4e
# Author: donnyaw
# Date: Mon Feb 10
#
# refactor: change auth token format

# 7. End bisect (go back to your branch)
git bisect reset

Automated Bisect

If you have a test script that exits 0 for good and non-zero for bad:

git bisect start HEAD v1.0
git bisect run npm test
# Git automatically tests each commit and finds the culprit!

git bisect reset

Decision Guide

What You WantCommand
Copy one commit to current branchgit cherry-pick <hash>
Copy commits without committinggit cherry-pick --no-commit <hash>
Find which commit introduced a buggit bisect start + good / bad
Automate bug findinggit bisect run <test-script>

Best Practices

  • Prefer merge/rebase over cherry-pick — cherry-pick should be for exceptional cases
  • Use bisect with automated tests — eliminates human error in the search process
  • Always git bisect reset when done — returns you to your original branch
  • Document cherry-picked commits — note the source in the commit message

What's Next

  1. Submodules & Subtrees — Include external repositories in your project
  2. Hooks & Automation — Automate tasks with Git hooks