git 如何挑选多个提交

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1670970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 07:18:13  来源:igfitidea点击:

How to cherry-pick multiple commits

gitgit-rebasecherry-pick

提问by tig

I have two branches. Commit ais the head of one, while the other has b, c, d, eand fon top of a. I want to move c, d, eand fto first branch without commit b. Using cherry pick it is easy: checkout first branch cherry-pick one by one cto fand rebase second branch onto first. But is there any way to cherry-pick all c-fin one command?

我有两个分支。Commita是一个的头部,而另一个有b, c, d,ef在 之上a。我想移动cdef第一支没有提交b。使用cherry pick很容易:一个一个c地结帐第一个分支cherry-pickf并将第二个分支重新设置到第一个上。但有什么办法可以摘樱桃所有c-f在一个命令?

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

这是场景的视觉描述(感谢JJD):

enter image description here

在此处输入图片说明

回答by Eric Darchis

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

Git 1.7.2 引入了挑选一系列提交的能力。从发行说明

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

git cherry-pick学会了选择一系列提交(例如cherry-pick A..Bcherry-pick --stdin),也是如此git revert;但是,这些不支持更好的排序控制rebase [-i]

To cherry-pick all the commits from commit Ato commit B(where Ais older than B), run:

要从提交A到提交BA比 更早的地方B)挑选所有提交,请运行:

git cherry-pick A^..B

If you want to ignoreA itself, run:

如果要忽略A 本身,请运行:

git cherry-pick A..B

(Credit goes to damian, J. B. Rainsberger and sschaef in the comments)

(在评论中归功于 damian、JB Rainsberger 和 sschaef)

回答by CB Bailey

The simplest way to do this is with the ontooption to rebase. Suppose that the branch which current finishes at ais called mybranch and this is the branch that you want to move c-fonto.

要做到这一点,最简单的方法是使用onto选项rebase。假设在支路电流结束a被称为mybranch,这是你要移动的分支c-f到。

# 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

回答by wolfc

Or the requested one-liner:

或要求的单线:

git rebase --onto a b f

回答by JJD

You can use a serial combination of git rebaseand git branchto apply a group of commits onto another branch. As already posted by wolfcthe 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.

您可以使用的串联组合git rebase,并git branch申请一集团承诺的到另一个分支。正如wolfc已经发布的那样,第一个命令实际上复制了提交。但是,在将分支名称添加到组的最顶部提交之前,更改是不可见的。

Please open the picture in a new tab ...

请在新标签页中打开图片...

Workflow

工作流程

To summarize the commands in text form:

以文本形式总结命令:

  1. Open gitkas a independent process using the command: gitk --all &.
  2. Run git rebase --onto a b f.
  3. Press F5in gitk. Nothing changes. But no HEADis marked.
  4. Run git branch selection
  5. Press F5in gitk. The new branch with its commits appears.
  1. 开放gitk如使用所述命令的独立的过程:gitk --all &
  2. 运行git rebase --onto a b f
  3. F5gitk。没有什么改变。但没有HEAD被标记。
  4. git branch selection
  5. F5gitk。带有提交的新分支出现。

This should clarify things:

这应该澄清一些事情:

  • Commit ais the new root destination of the group.
  • Commit bis the commit before the first commit of the group (exclusive).
  • Commit fis the last commit of the group (inclusive).
  • Commita是组的新根目标。
  • Commitb是组的第一次提交之前的提交(独占)。
  • Commitf是组的最后一次提交(包括)。

Afterwards, you could use git checkout feature && git reset --hard bto delete the commits ctill ffrom the featurebranch.

之后,你可以使用git checkout feature && git reset --hard b删除提交c,直到ffeature分支。

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

除了这个答案,我还写了一篇博客文章,描述了另一个场景中的命令,这应该有助于普遍使用它。

回答by Andy

To apply J. B. Rainsberger and sschaef's comments to specifically answer the question... To use a cherry-pick range on this example:

要应用 JB Rainsberger 和 sschaef 的评论来专门回答这个问题......在这个例子中使用樱桃挑选范围:

git checkout a
git cherry-pick b..f

or

或者

git checkout a
git cherry-pick c^..f

回答by Shrikant Wandhare

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:

如果您有选择性的修订要合并,例如来自 A、B、C、D、E、F、G、H、I、J 提交的 A、C、F、J,只需使用以下命令:

git cherry-pick A C F J

git 挑选 ACFJ

回答by Dustin

git rev-list --reverse b..f | xargs -n 1 git cherry-pick

回答by ut9081

To cherry pick from a commit id up to the tip of the branch, you can use:

要从提交 id 中挑选到分支的尖端,您可以使用:

git cherry-pick commit_id^..branch_name

git cherry-pick commit_id^..branch_name

回答by Nick F

Another variant worth mentioning is that if you want the last ncommits from a branch, the ~syntax can be useful:

另一个值得一提的变体是,如果您想要n来自分支的最后一次提交,则~语法可能很有用:

git cherry-pick some-branch~4..some-branch

In this case, the above command would pick the last 4 commits from a branch called some-branch(though you could also use a commit hash in place of a branch name)

在这种情况下,上面的命令将从名为的分支中选择最后 4 个提交some-branch(尽管您也可以使用提交哈希代替分支名称)

回答by ealfonso

Actually, the simplest way to do it could be to:

实际上,最简单的方法可能是:

  1. record the merge-base between the two branches: MERGE_BASE=$(git merge-base branch-a branch-b)
  2. fast-forward or rebase the older branch onto the newer branch
  3. rebase the resulting branch onto itself, starting at the merge base from step 1, and manually remove commits that are not desired:

    git rebase ${SAVED_MERGE_BASE} -i
    

    Alternatively, if there are only a few new commits, skip step 1, and simply use

    git rebase HEAD^^^^^^^ -i
    

    in the first step, using enough ^to move past the merge-base.

  1. 记录两个分支之间的合并基: MERGE_BASE=$(git merge-base branch-a branch-b)
  2. 将旧分支快进或变基到新分支上
  3. 从步骤 1 的合并基础开始,将生成的分支重新绑定到自身,并手动删除不需要的提交:

    git rebase ${SAVED_MERGE_BASE} -i
    

    或者,如果只有几个新提交,请跳过步骤 1,只需使用

    git rebase HEAD^^^^^^^ -i
    

    在第一步中,使用足够^的移动通过合并基础。

You will see something like this in the interactive rebase:

您将在交互式 rebase 中看到类似的内容:

pick 3139276 commit a
pick c1b421d commit b
pick 7204ee5 commit c
pick 6ae9419 commit d
pick 0152077 commit e
pick 2656623 commit f

Then remove lines b (and any others you want)

然后删除行 b (以及您想要的任何其他行)