Gitastic
Path › Part 5: Power tools › Lesson 14 of 16
14

Cherry-pick: copy one commit

Take exactly the commit you need — and nothing else.

1 Learn the idea

Sometimes a branch contains one commit you need right now — say a bug fix buried in a half-finished feature branch. Merging would drag in everything else. git cherry-pick copies just that one commit onto the branch you are on.

What actually happens

  1. Git looks at the chosen commit and works out what it changed compared to its parent.
  2. It applies those same changes on top of HEAD.
  3. It creates a brand-new commit with the same message — but a different hash, because it has a different parent.

2 Watch it happen

Rescue a bug fix from a feature branch

Press Play or use → to step through. Watch the graph as each command runs.

e00120d Initial appe00120dInitial app085803b Add search box085803bAdd search boxab5cbe1 Fix crash on empty inputab5cbe1Fix crash on e…c29abae Add search results pagec29abaeAdd search res…HEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)mainBranch "feature" — a movable pointerfeature
terminal · simulated, no real repository is touched
Read this demo as text
  1. $ git log --oneline --all

    The feature branch has three commits. The middle one fixes a crash that is also hurting users on main today. The search feature is not ready yet.

  2. $ git switch main

    We are on main, the branch that should receive the fix. Cherry-pick always copies onto the branch you are on.

  3. $ git cherry-pick feature~1

    feature~1 means "one commit before the tip of feature" — the crash fix. Git replays its change on top of main and makes a new commit.

  4. $ git log --oneline --all

    Look closely: the fix now exists twice, with the same message but different hashes. The original on feature is untouched.

  5. $ ls

    Only app.js got the fix. search.js and results.js did not come along — that is the whole point.

  6. $ git show HEAD

    git show confirms the new commit contains exactly the same change as the original.

  7. $ git merge feature

    Later, when the feature is done, merging still works: git sees both sides made the identical change to app.js, so there is nothing to argue about.

git merge feature
  • Brings in every commit of the branch
  • Keeps the original commits
  • Branches stay connected in the graph
git cherry-pick <commit>
  • Brings in exactly one commit
  • Creates a copy with a new hash
  • No connection between the branches
git cherry-pick <commit>Copy one commit onto the current branch
git cherry-pick feature~1Refer to commits relative to a branch tip
git cherry-pick --continueFinish after fixing a conflict
git cherry-pick --abortGive up and return to where you were

3 Check your understanding

Question 1

You cherry-pick commit a1b2c3d from feature onto main. What is the hash of the new commit on main?

Question 2

In this graph, you are on main. Which command brings only "Fix typo in footer" onto main?

565a023 Initial site565a023Initial site7909ad8 New color scheme7909ad8New color sche…22cf8f9 Fix typo in footer22cf8f9Fix typo in fo…1663c97 New logo1663c97New logoHEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)mainBranch "redesign" — a movable pointerredesign
Question 3

A cherry-pick stops with a CONFLICT. What is the right sequence to finish it?

Question 4

When is merge the better choice over cherry-pick?

4 Practice for real

Your mission

Grab just the fix

The experiment branch has a real bug fix ("Fix login bug") sandwiched between two wild experiments. Get only the login fix onto main. The experiments must not reach main, and experiment must stay as it is.

e00120d Initial app click to insert the hash into the terminale00120dInitial appc919fb6 Try new theme click to insert the hash into the terminalc919fb6Try new theme9f40464 Fix login bug click to insert the hash into the terminal9f40464Fix login bug7158690 Rewrite everything in Rust click to insert the hash into the terminal7158690Rewrite everyt…HEAD = where you are. It points at the current branch.HEAD →Branch "main" — a movable pointer (current branch: moves when you commit)mainBranch "experiment" — a movable pointerexperiment
terminal · simulated, no real repository is touched
Type commands below. `help` lists everything. Tab completes, ↑ recalls. Click a commit to paste its hash.
~/project (main) $