如何针对同一个 git 版本应用两个补丁?

Posted

技术标签:

【中文标题】如何针对同一个 git 版本应用两个补丁?【英文标题】:How to apply two patches against the same git revision? 【发布时间】:2011-03-07 15:07:24 【问题描述】:

这是一个虚构的问题,但我在使用补丁时遇到了实际问题。假设我有一个具有以下 git 历史的项目:

A - B - C

现在,如果我收到两个补丁,C1C2,它们打算应用于 C,我应该如何处理它们?如果我先应用补丁C1,那么我将无法应用补丁C2,因为存储库已变为:

A - B - C - C1

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

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

A - B - C - D - E

然后我检查了我的电子邮件并收到了C 的补丁。 再次,是否可以简单地应用该补丁,还是我必须要求更新补丁?

【问题讨论】:

你能像这里解释的那样进行多路合并:book.git-scm.com/5_advanced_branching_and_merging.html 吗? @Augusto 我可以合并补丁吗?我想我只能应用补丁,不能合并。或者用 git 可以吗? 我的错-我认为补丁是指带有补丁的分支的链接。保持相同的概念,您可以从 C 创建 2 个功能分支,对每个功能分支应用补丁,然后将它们合并到头部...我相信这会起作用,但听起来需要做很多工作我,也许有人有更好的解决方案。 【参考方案1】:

经典的方法是:

应用收到的第一个补丁, 拒绝任何不是快进的补丁,并要求发件人先 rebase 他/她的 repo,然后重新检查补丁,然后重新发送。

一般的想法是,解决合并冲突不是由您来决定的:只有补丁的创建者才有必要的知识来解决与当前源代码的任何冲突。

正如 Linus Torvalds(Git 的创建者)在 his 2007 Google talk 中所说:

因此,请记住,分配意味着没有人是特别的。 所以我没有合并,而是推出了我的第一棵树,它没有任何合并问题,然后我告诉第二个人:

“嘿,我试图从你那里拉出来,但我有合并冲突,而且它们并不是完全无关紧要的,所以我决定你来代替荣誉。”

他们确实做到了。他们知道自己在做什么,因为这是他们的改变。所以他们可以进行合并,他们可能认为我是个白痴,因为合并是如此简单,很明显我应该采用他们的代码,但他们进行了合并并更新了他们的树,然后说“嘿,你能拉现在从我这里”,我从他们那里拉出来,他们为我做了所有的工作。

就是这样:他们为我做了所有的工作。所以,...我相信。现在我只需要弄清楚第 3 步:利润

【讨论】:

【参考方案2】:

大多数时候,C2 将在 C1 之上应用。只有当它们编辑相同文件的重叠部分时,您才会遇到合并冲突。 Git 将获取补丁中所有冲突的部分,并插入有助于解决合并的冲突标记。

至于做什么,这取决于您的项目有多大以及您在该部分代码中的能力如何——只要提交者使用了合理的近期结帐,我总是自己解决冲突作为他们补丁的基础。

另一位评论者提到了 Linus 的引述,他说他总是让其他人解决冲突,但即使这样也不完全正确;他经常要求人们在发送拉取请求时留下未解决的冲突,以便他对他们开枪。

【讨论】:

+1 from "another commenter";) 我对 Linux 的引用有点讽刺,因为它不是一个通用的解决方案,只是 DVCS 过程及其“出版物”的一个很好的说明" 工作流程 (***.com/questions/2563836/…)。【参考方案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。

当然,如果合并失败,而且看起来太吓人而无法自行整理,只需将其吹走,然后告诉 C2 的提交者自己修复它。 (git reset --merge; git branch -D C2)

【讨论】:

因此,您将第二个风险更高的补丁隔离在其自己的本地分支中,然后如果一切顺利,则将其合并到 C 中。好的。 +1

以上是关于如何针对同一个 git 版本应用两个补丁?的主要内容,如果未能解决你的问题,请参考以下文章

如何应用使用 git format-patch 生成的补丁?

如何将 git 补丁从一个存储库应用到另一个存储库?

如何将 Git 补丁应用于具有不同名称和路径的文件?

从 git 存储库创建补丁或差异文件并将其应用到另一个不同的 git 存储库

如何在未安装 Git 的情况下应用“git diff”补丁?

关于git的认知