git - 如何挑选一系列提交并将它们 merge 到另一个分支中?

标签 git git-merge git-cherry-pick

我有以下存储库布局:

  • master 分支(生产)
  • 整合
  • 工作

我想要实现的是从工作分支中挑选一系列提交并将其 merge 到集成分支中。我是 git 的新手,我无法弄清楚如何在不弄乱存储库的情况下准确地做到这一点(在一次操作中挑选提交范围,而不是 merge )。对此有任何指示或想法吗?谢谢!

最佳答案

当涉及一系列提交时, cherry-pick 不切实际。

作为mentioned below通过 Keith Kim , Git 1.7.2+ 引入了挑选一系列提交的能力(但你仍然需要注意 consequence of cherry-picking for future merge )

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.

damian comments并警告我们:

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

如果你想选择范围BD(包括B)那将是B^..D(而不是 B..D)。
请参见“Git create branch from range of previous commits?”作为说明。

作为Jubobs提及 in the comments :

This assumes that B is not a root commit; you'll get an "unknown revision" error otherwise.

注意:从 Git 2.9.x/2.10(2016 年第三季度)开始,您可以直接在孤立分支(空头)上挑选一系列提交:参见“How to make existing branch an orphan in git”。


原始答案(2010 年 1 月)

rebase --onto 会更好,您可以在集成分支之上重放给定范围的提交,如 Charles Bailey described here .
(另外,在 git rebase man page 中查找“这是如何将基于一个分支的主题分支移植到另一个分支”,以查看 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 --onto 之后,integration 将回到集成分支的最后一次提交(即“tmp”分支+ 所有重播的提交)

使用 cherry-picking 或 rebase --onto,不要忘记它对后续 merge 有影响,如 described here .


一个纯粹的“cherry-pick”解决方案是 discussed here ,并且会涉及类似的事情:

If you want to use a patch approach then "git format-patch|git am" and "git cherry" are your options.
Currently, git cherry-pick accepts only a single commit, but if you want to pick the range B through D that would be B^..D in git lingo, so

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

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

关于git - 如何挑选一系列提交并将它们 merge 到另一个分支中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1994463/

相关文章:

linux - git push 后项目从 gitweb 消失

git - git URL 中的 ".git"是什么意思?

git - 检查分支是否已经 merge 到远程的 master 或 dev 分支中

git - Big git merge - 跨提交拆分分辨率

git - Git 中的 merge 是对称的吗?

git 从 pull 请求中删除提交

git - .git/sequencer 目录是什么?

checkout 、 pull 、 checkout 、 merge/ rebase 的 Git 快捷方式

git - 使用 SHA ID 修改旧提交的评论消息