How to cherry-pick multiple commits

2019-01-01 02:25发布

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):

enter image description here

9条回答
荒废的爱情
2楼-- · 2019-01-01 03:03

Git 1.7.2 introduced the ability to cherrypick 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.


Including important comments (credits to respective authors)

Note 1: In the "cherry-pick A..B" form, A should be older than B. If they're the wrong order the command will silently fail. – damian

Note 2: Also, this will not cherry-pick A, but rather everything after A up to and including B. – J. B. Rainsberger

Note 3: To include A just type git cherry-pick A^..B – sschaef

查看更多
与君花间醉酒
3楼-- · 2019-01-01 03:05

You can use a serial combination of git rebase and git branch to apply a group of commits onto another branch. As already posted by wolfc the first command actually copies the commits. However, the change is not visible until you add a branch name to the top most commit of the group.

Please open the picture in a new tab ...

Workflow

To summarize the commands in text form:

  1. Open gitk as a independent process using the command: gitk --all &.
  2. Run git rebase --onto a b f.
  3. Press F5 in gitk. Nothing changes. But no HEAD is marked.
  4. Run git branch selection
  5. Press F5 in gitk. The new branch with its commits appears.

This should clarify things:

  • Commit a is the new root destination of the group.
  • Commit b is the commit before the first commit of the group (exclusive).
  • Commit f is the last commit of the group (inclusive).

Afterwards, you could use git checkout feature && git reset --hard b to delete the commits c till f from the feature branch.

In addition to this answer, I wrote a blog post which describes the commands in another scenario which should help to generally use it.

查看更多
低头抚发
4楼-- · 2019-01-01 03:12
git rev-list --reverse b..f | xargs -n 1 git cherry-pick
查看更多
皆成旧梦
5楼-- · 2019-01-01 03:13

The simplest way to do this is with the onto option to rebase. Suppose that the branch which current finishes at a is called mybranch and this is the branch that you want to move c-f onto.

# checkout mybranch
git checkout mybranch

# reset it to f (currently includes a)
git reset --hard f

# rebase every commit after b and transplant it onto a
git rebase --onto a b
查看更多
谁念西风独自凉
6楼-- · 2019-01-01 03:14
git format-patch --full-index --binary --stdout range... | git am -3
查看更多
明月照影归
7楼-- · 2019-01-01 03:19

If you have selective revisions to merge, say A, C, F, J from A,B,C,D,E,F,G,H,I,J commits, simply use below command:

git cherry-pick A C F J

查看更多
登录 后发表回答