Search code examples
gitgit-rebasecherry-pickgit-cherry-pick

How to cherry-pick multiple commits


I have two branches. Commit a is the head of one, while the other has b, c, d, e and f on top of a. I want to move c, d, e and f to first branch without commit b. Using cherry pick it is easy: checkout first branch cherry-pick one by one c to f and rebase second branch onto first. But is there any way to cherry-pick all c-f in one command?

Here is a visual description of the scenario (thanks JJD):

A commit showing a 'before' and 'after' state. In the 'before' state, commits a through f are connected in one contiguous sequence. In the after state, commits c through f have been relocated to directly connect to a without reordering, leaving the b commit behind.


Solution

  • Git 1.7.2 introduced the ability to cherry pick a range of commits. From the release notes:

    git cherry-pick learned to pick a range of commits (e.g. cherry-pick A..B and cherry-pick --stdin), so did git revert; these do not support the nicer sequencing control rebase [-i] has, though.

    To cherry-pick all the commits from commit A to commit B (where A is older than B), run:

    git cherry-pick A^..B
    

    If you want to ignore A itself, run:

    git cherry-pick A..B
    

    Notes from comments:

    • A should be older than B, or A should be from another branch.
    • On Windows, it should be A^^..B as the caret needs to be escaped, or it should be "A^..B" (double quotes).
    • In zsh shell, it should be 'A^..B' (single quotes) as the caret is a special character.
    • For an exposition, see the answer by Gabriel Staples.

    (Credits to damian, J. B. Rainsberger, sschaef, Neptilo, Pete and TMin in the comments.)