协慌网

登录 贡献 社区

如何挑选一系列提交并合并到另一个分支?

我有以下存储库布局:

  • 主分支(生产)
  • 一体化
  • 在职的

我想要实现的是从工作分支中挑选一系列提交并将其合并到集成分支中。我对 git 很陌生,我不知道如何准确地做到这一点(在一个操作中选择合并范围而不是合并中的提交范围)而不弄乱存储库。有任何指示或想法吗?谢谢!

答案

当涉及到一系列提交时,挑选樱桃不实际的。

就像Keith Kim在下面提到的那样,Git 1.7.2 + 引入了对一系列提交进行樱桃选择的能力(但是您仍然需要意识到为未来的合并选择樱桃的后果)。

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

达米安评论并警告我们:

在 “ cherry-pick A..B ” 格式中, A应该早于B
如果它们的顺序错误,命令将无提示地失败

如果要选择范围BD (包括B ,则范围应为B^..D (而不是B..D )。
请参阅 “ Git 从先前提交的范围创建分支? ” 作为插图。

正如Jubobs 在评论中提到的那样:

假设B不是根提交;否则,您将收到 “ unknown revision ” 错误。

注意:从 Git 2.9.x / 2.10(2016 年第三季度)开始,您可以直接在孤儿分支(空头)上挑选一系列提交:请参阅 “如何在 git 中使现有分支成为孤儿”。


原始答案(2010 年 1 月)

进行rebase --onto会更好,因为您可以在集成分支的顶部重播给定的提交范围,如Charles Bailey 在此处所述
(另外,在 git rebase 手册页中查找 “这是将基于一个分支的主题分支移植到另一个分支的方法,以查看git rebase --onto的实际示例)”

如果您当前的分支是集成:

# Checkout a new temporary branch at the current location
git checkout -b tmp

# Move the integration branch to the head of the new patchset
git branch -f integration last_SHA-1_of_working_branch_range

# Rebase the patchset onto tmp, the old location of integration
git rebase --onto tmp first_SHA-1_of_working_branch_range~1 integration

这将重播介于以下之间的所有内容:

  • first_SHA-1_of_working_branch_range的父级之后(因此~1 ):要重播的第一个提交
  • 直到 “ integration ”(指向您要从working分支重播的最后一个提交)

到 “ tmp ”(指向integration之前指向的位置)

如果在重播这些提交之一时存在任何冲突,请执行以下操作:

  • 要么解决它,然后运行 “ git rebase --continue ”。
  • 或跳过此补丁,而是运行 “ git rebase --skip
  • 或使用 “ git rebase --abort ” 取消所有操作(并将integration分支tmp分支)

重新rebase --ontointegration将返回到集成分支的最后一次提交(即 “ tmp ” 分支 + 所有重播的提交)

进行樱桃选择或rebase --onto ,请不要忘记它会对后续合并产生影响,如此处所述


这里讨论了一个纯 “ cherry-pick ” 解决方案,其中涉及到以下内容:

如果要使用补丁方法,则可以选择 “git format-patch | git am” 和 “git cherry”。
目前, git cherry-pick仅接受一次提交,但是如果您要选择范围BD ,则在 git lingo 中B^..D

git rev-list --reverse --topo-order B^..D | while read rev 
do 
  git cherry-pick $rev || break 
done

但是无论如何,当您需要 “重播” 一系列提交时,单词 “replay” 应该促使您使用rebase ” 功能。

从 git v1.7.2 开始,cherry pick 可以接受一系列提交:

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

假设您有 2 个分支,

“branchA”:包括您要复制的提交(从 “commitA” 到 “commitB”

“branchB”:要从 “branchA” 转移提交的分支

1)

git checkout <branchA>

2)获取 “commitA” 和 “commitB” 的 ID

3)

git checkout <branchB>

4)

git cherry-pick <commitA>^..<commitB>

5)如果有冲突,请解决并输入

git cherry-pick --continue

继续进行摘樱桃的过程。