Great work!

XP to next level

BugEater
EN

Moving One Commit Without Merging a Branch

Learning Objectives

By the end of this lesson you will be able to:

  • Copy a single commit from one branch to another with git cherry-pick
  • Explain why the copy has a different ID from the original
  • Find the commit ID you need before picking it
  • Say when cherry-pick is the right tool and when merge is

The Problem It Solves

release/4.2 is frozen for regression testing. A developer has fixed a null-pointer crash on develop, in a branch that also contains three half-finished features.

You need that one fix on the frozen branch. You cannot merge — that brings the features too, and the whole point of a freeze is that nothing else arrives. Copying the diff by hand loses the author, the message and the traceability.

git switch release/4.2
git cherry-pick 8f3c2a1

Done. The crash fix is on the release branch, and nothing else came with it.

What It Actually Does

Cherry-pick takes the change introduced by one commit — the diff between it and its parent — and applies that change where you are standing, as a new commit.

Before:
                 8f3c2a1
                    │
  A───B───C───D───E───F      develop
   \
    G───H                    release/4.2   ← you are here

After git cherry-pick 8f3c2a1:

  A───B───C───D───E───F      develop
   \
    G───H───8f3c2a1'         release/4.2

The apostrophe is doing the same work it did in Module 1. 8f3c2a1' is a new commit with a new ID, because its parent is H rather than E, and a commit's ID hashes its parent.

What is preserved: the diff, the commit message, the original author and author date. What is new: the commit ID, the parent, and the committer date.

This is why git log on the release branch shows the developer's name, not yours, even though you performed the copy. Git distinguishes the author (who wrote it) from the committer (who put it here).

Finding the Commit

You rarely have the ID in hand. Three reliable ways to get it:

git log --oneline develop -20

The straightforward option when you know roughly when it landed.

git log --oneline --grep="null pointer" develop

Search commit messages. Fast when the team writes decent messages.

git log --oneline -S "getUserPreferences" develop

The pickaxe from the previous trail: find commits that changed the number of occurrences of that string. This is the one that works when the message is useless.

Once you have a candidate, read it before you pick it:

git show 8f3c2a1

Confirm it contains only the fix. A commit that also renamed six files is a commit that will bring those renames with it.

Cherry-Pick or Merge?

Use
You want one specific commit cherry-pick
You want everything on that branch merge
The branch will be merged later anyway merge — picking now creates a duplicate
The target branch is frozen or a release cherry-pick
You want a fix on two branches at once cherry-pick onto the second

The third row is the one to remember. If the source branch is going to be merged into your target eventually, cherry-picking now means the same change arrives twice. Git usually copes, but "usually" is doing real work in that sentence, and Lesson 4 is entirely about it.

Picking Several Commits

Multiple IDs are allowed, applied in the order you list them:

git cherry-pick 8f3c2a1 4d9e7b2

If a pick conflicts partway through a list, the ones before it stay applied — exactly like a rebase stopping mid-flight. The same three exits apply, and they are Lesson 3.

Pro Tip: Cherry-pick from a clean working tree, every time. The command stops and refuses if you have uncommitted changes, and the message is easy to misread as something being wrong with the commit you picked.

For a Tester Specifically

Three recurring uses:

Verifying a fix in isolation. Put one candidate commit on a clean branch built from the last known-good release, and test only that. If the bug is gone, the fix works; if it is not, you have ruled out interference from everything else on the developer's branch.

Backporting. A bug found in production, fixed on develop, needed on release/4.2 tonight. This is the canonical case.

Building a minimal reproduction. Pick the commit you suspect onto a branch from before it, and you have a two-commit repository that either shows the bug or does not. That is a much better bug report than a branch name.

Key Takeaways

  • git cherry-pick <sha> applies one commit's change where you are standing, as a new commit
  • The copy keeps the diff, message and original author; it gets a new ID and parent
  • Find the commit with git log --oneline, --grep or -S, and read it with git show first
  • Cherry-pick for one commit; merge when you want the whole branch
  • Picking from a branch that will later be merged creates a duplicate — see Lesson 4
  • Several commits can be picked at once, applied in the order given
  • Always start from a clean working tree

Quiz

What does git cherry-pick 8f3c2a1 apply to your current branch?

Why does the cherry-picked commit have a different ID from the original?

After you cherry-pick a colleague's fix, whose name does git log show as the author?

feature/search will be merged into main next sprint. You cherry-pick one of its commits into main today. What have you set up?