我有两个分支。提交a
是一个的头,而其他有b
, c
, d
, e
和f
之上a
。我想将c
, d
, e
和f
移到第一个分支而不提交b
。使用樱桃挑选很容易:以c
到f
逐一签出第一个分支,然后将第二个分支重新设置为第一个分支。但是,有什么方法可以在一个命令中挑选所有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 rebase
和git branch
的串行组合将一组提交应用于另一个分支。正如Wolfc已经发布的 ,第一个命令实际上是复制提交。但是,直到将分支名称添加到组的最顶部提交后,更改才可见。
请在新标签页中打开图片...
要以文本形式汇总命令:
gitk --all &
。 git rebase --onto abf
。 HEAD
被标记。 git branch selection
这应该使事情变得清晰:
a
是该组的新根目标。 b
是组中第一次提交之前的提交(不包括)。 f
是该组的最后一次提交(含)。 之后,您可以使用git checkout feature && git reset --hard b
从feature
分支中删除提交c
到f
。
除了这个答案之外,我还写了一篇博客文章 ,描述了另一种情况下的命令,这应该有助于通常使用它。
要应用 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
实际上,最简单的方法是:
MERGE_BASE=$(git merge-base branch-a branch-b)
从第 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 行(以及您想要的其他任何行)