如何挑选多个提交

我有两个分支。提交a是一个的头,而其他有bcdef之上a 。我想将cdef移到第一个分支而不提交b 。使用樱桃挑选很容易:以cf逐一签出第一个分支,然后将第二个分支重新设置为第一个分支。但是,有什么方法可以在一个命令中挑选所有c - f吗?

这是该场景的直观描述(感谢JJD ):

在此处输入图片说明

答案

Git 1.7.2 引入了选择一系列提交的功能。从发行说明中

git cherry-pick”学会了选择一系列提交(例如 “cherry-pick A..B” 和 “cherry-pick --stdin”),“git revert” 也是如此;它们不支持更好的排序控制“重新设置[-i]”。


包括重要评论(对各自作者的感谢)

注意 1:在 “cherry-pick A..B” 格式中,A 应该早于 B。如果输入的顺序错误,命令将无提示地失败。 –达米安

注意 2:此外,这不会挑剔 A,而是从 A 到 B(包括 B)之后的所有内容。– JB Rainsberger

注意 3:要包含 A,只需键入 git cherry-pick A ^ .. B – sschaef

要做到这一点,最简单的方法是使用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

或要求的单线:

git rebase --onto a b f

您可以使用git rebasegit branch的串行组合将一组提交应用于另一个分支。正如Wolfc已经发布的 ,第一个命令实际上是复制提交。但是,直到将分支名称添加到组的最顶部提交后,更改才可见。

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

工作流程

要以文本形式汇总命令:

  1. 使用以下命令将gitk作为独立进程打开: gitk --all &
  2. 运行git rebase --onto abf
  3. gitk 中F5 键 。没有什么改变。但是没有HEAD被标记。
  4. 运行git branch selection
  5. gitk 中F5 键 。出现带有提交的新分支。

这应该使事情变得清晰:

  • 提交a是该组的新根目标。
  • 提交b是组中第一次提交之前的提交(不包括)。
  • 提交f是该组的最后一次提交(含)。

之后,您可以使用git checkout feature && git reset --hard bfeature分支中删除提交cf

除了这个答案之外,我还写了一篇博客文章 ,描述了另一种情况下的命令,这应该有助于通常使用它。

要应用 JB Rainsberger 和 sschaef 的评论来专门回答这个问题,请执行以下操作:在此示例中使用 Cherry-pick 范围:

git checkout a
git cherry-pick b..f

要么

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

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

git cherry-pick ACFJ

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

要从提交 ID 到分支的尖端进行挑选,可以使用:

git cherry-pick commit_id^..branch_name

git format-patch --full-index --binary --stdout range... | git am -3

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

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

    git rebase ${SAVED_MERGE_BASE} -i

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

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

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

您将在交互式资源库中看到以下内容:

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

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