如何在同一git版本中应用两个补丁?

12

这是一个虚构的问题,但我在处理补丁方面遇到了真正的问题。假设我有一个具有以下Git历史记录的项目:

A - B - C

如果我收到两个补丁 C1C2,这些补丁是要应用在 C 上的,我应该如何处理它们呢?如果我先应用补丁 C1,那么我将无法应用补丁 C2,因为代码库已经变成了:

A - B - C - C1

我是否可以同时应用它们,还是必须回复发送 C2 的人告诉他/她更新补丁?

现在假设我离线工作并提交,以便仓库变为:

A - B - C - D - E

然后我查看了我的电子邮件,并收到了一个关于C的补丁程序。那么,我只需应用该补丁,还是我需要要求更新该补丁?


你能按照这里所解释的方式进行多路合并吗:http://book.git-scm.com/5_advanced_branching_and_merging.html? - Augusto
@Augusto 我可以合并补丁吗?我认为我只能应用补丁,而不能合并。或者在git中是否可能? - phunehehe
我的错 - 我认为“patches”是指一个带有补丁的分支链接。保持相同的概念,你可以从 C 分支创建 2 个特性分支,将补丁应用于每个特性分支,然后将它们合并到主分支... 我相信这会起作用,但对我来说似乎需要做很多工作,也许有更好的解决方案。 - Augusto
3个回答

8

经典的方式是:

  • 应用收到的第一个补丁,
  • 拒绝任何不是快进的补丁,并要求发送者先将其仓库变基,然后重新检查补丁并重新发送。

总的思路是你不能解决合并冲突:只有补丁的创建者才有必要的知识来解决当前源代码的任何冲突。

正如 Git 的创建者 Linus Torvalds 在 他2007年的 Google 演讲 中所说:

所以发生的事情是,记住,分布意味着没有人特别。因此,我不是合并,而是推出我的第一个树,它没有任何合并问题,然后我告诉第二个人:“嘿,我试图从你这里拉取,但我有合并冲突,并且它们不完全是琐事,所以我决定让你来做这件事。”他们知道自己在做什么,因为这是他们的更改。所以他们可以进行合并,他们可能认为我是个白痴,因为合并如此简单,很明显我应该采用他们的代码,但他们进行了合并并更新了他们的树,然后说“嘿,你现在可以从我这里拉取了”,我从他们那里拉取并且他们为我完成了所有工作。这就是全部内容:他们为我完成了所有工作,因此...我获得了功劳。现在我只需要找出步骤3:利润。

5
大多数情况下,C2会覆盖C1。只有当它们是对同一文件的重叠部分进行编辑时,才会出现合并冲突。Git将采取所有不冲突的补丁部分,并插入帮助您解决合并的冲突标记。
至于该怎么做,这取决于您的项目有多大以及您在代码的哪个部分上有多少能力 - 只要提交者使用了相对较新的检出作为其补丁的基础,我总是自己修复冲突。
另一个评论者提到了Linus的名言,说他总是让别人解决冲突,但即使这也不完全正确;他经常要求人们在发送拉取请求时不解决冲突,以便他有机会处理它们。

来自“另一位评论者”的+1;) 我在Linux上的引用有点玩笑,因为它并不是一个通用的解决方案,只是DVCS过程及其“发布”工作流程的一个很好的例证(https://dev59.com/03E85IYBdhLWcg3w43sW#2563917)。 - VonC

3
你至少可以尝试应用所有这些补丁。你可能会遇到合并冲突,正如VonC所建议的那样,你可能希望补丁提交者解决它们,或者像cjb所说的那样自己解决冲突!无论哪种情况,以下是你需要做的。
第一种情况:两个补丁,C1和C2。
# apply C1
git am C1.patch
# create a temporary branch (use a real name instead of C2)
git checkout -b C2 C
# apply C2
git am C2.patch
# return to master
git checkout master
# merge the other branch
git merge C2
# and delete the other branch
git branch -d C2

您可以类似地处理第二种情况;只是您自己提交了D和E,而不是应用C1。

当然,如果合并失败,看起来太可怕了,您无法自己整理,那就把它删除,并告诉提交者在他们的端口上修复它。 (git reset --merge; git branch -D C2)


所以你要将第二个 - 更有风险的 - 补丁隔离到自己的本地分支中,在一切顺利的情况下再将其合并到 C 中。很好。+1 - VonC

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接