在git中,我如何为最近的2个或更多版本创建一个单独的补丁?

71

我想创建一个针对最后两个版本的补丁。

git format-patch -2

给我两个补丁文件,每个文件对应一个版本。

git format-patch HEAD~2..HEAD

提供相同的内容。

git format-patch -1 HEAD~2..HEAD

在Git中有没有办法只获取最新版本的更改内容并保存为单个文件?


2
你能告诉我们更多关于你想做的事情的背景吗?你是否知道可以使用交互式变基将提交压缩在一起的功能?如果是这样,为什么你想要压缩发送给他人的补丁,但不压缩你历史记录中对应的提交? - Greg Bacon
@gbacon:实际上在发布这个问题后不久我学会了如何进行变基。你说得对,这是解决我的问题的更好方法。尽管如此,学习如何做这件事也无妨。 - Matthew
1
@GregBacon:我现在经常做的一件事是:在一个功能分支上工作,进行许多小的提交。当到了将该分支推送到主分支的时候,首先要压缩它。但同时,我使用 git diff master mybranch 来发送一个补丁进行审查,同时仍然保留我的小的提交历史(供自己使用)。 - Matthew
4个回答

71
git diff HEAD~2..HEAD > my-patch.diff

不过它将不包含 format-patch 的每个提交元数据。


2
显然,如果这两个提交的作者不同,那么它应该有哪个作者?2次提交更改的提交消息应该是什么样子?等等。 - Jakub Narębski
2
请注意,如果您使用功能分支,则可以执行 git diff master mybranch > my-patch.diff 来为该分支创建补丁。 - Matthew
这种方法会创建三个文件,而不是一个。 - Dominic Clifton

71

使用 --stdout 选项,然后将其通过 cat 命令输出至文件中。

就像这样:

git format-patch HEAD~2..HEAD --stdout > changes.patch

这将保留每个提交的元数据。


3
你得到的是一个 mbox 文件(连接的邮件文件),而不是补丁文件。你可以使用 git am 应用它,但不能使用标准的补丁工具。 - Tobu
1
@Tobu:但通常你想要使用git am应用提交,因为它保留了提交的原样,而不是一个大的代码块... - Smar
有没有办法将源的HEAD引用作为refspec的开头?!那将是惊人的,就像git format-patch origin/HEAD..HEAD --stdout > changes.patch这样...天哪,它起作用了。 - Ray Foss
这个解决方案比上面那个更好 - 如果有二进制文件(例如秘密文件),则它们不会包含在上面的解决方案中。这个解决方案还将生成一个完整的提交列表,放入一个大的补丁文件中,非常棒 - 如果需要压缩,稍后可以使用 git rebase -i 进行操作。 - John Basila

5

从Git 2.20(2018年第四季度)开始,您现在可以使用以下功能:

  • git format-patch --interdiff
  • git format-patch --rangediff

这两个功能都有助于解释此版本与封面信中的上一次尝试之间的差异(或作为注释放在树状线后面)。

format-patch:允许--interdiff/--rangediff应用于单补丁

当提交修订版的补丁或系列时,通常在封面信中包含自上一次尝试以来的更改摘要形式的interdiff(供审阅者参考)会很有帮助。
但是,尽管会产生噪音,但偶尔将interdiff或rangediff插入到单个1补丁系列的评论部分中仍然很有用。

请查看由Eric Sunshine (sunshineco)于2018年7月22日提交的提交ee6cbf7, 提交3fcc7a2, 提交3b02641, 提交5ac290f, 提交126facf, 提交fa5b7ea
(由Junio C Hamano -- gitster --合并于2018年9月17日的提交688cb1c)

因此,将“git format-patch --interdiff=<prev>”扩展为将interdiff插入独立补丁的评论部分,而不需要一个封面信。缩进interdiff以避免混淆git-am和读者认为它是正确的一部分。

请参阅 提交记录 40ce416, 提交记录 8631bf1, 提交记录 4ee9968, 提交记录 2e6fd71, 提交记录 31e2617, 提交记录 73a834e, 提交记录 2566865, 提交记录 87f1b2d (2018年7月22日) 由 Eric Sunshine (sunshineco) 提交。
(在 提交记录 881c019 中由 Junio C Hamano -- gitster -- 合并,2018年9月17日)

因此,将“git format-patch --range-diff=<refspec>”扩展到将range-diff插入单独补丁的评论部分,而不需要一个封面信。

那么,git format-patch --range-diff=<commit hash> 会生成一个仅包含所需提交的补丁,并且不会在每个更改的文件中添加 PATCH 字母? - ZeroPhase
据我所知,@ZeroPhase没有补丁信。 (https://git-scm.com/docs/git-format-patch#Documentation/git-format-patch.txt---range-diffltpreviousgt) - VonC

-2
你可以这样做:
$ git checkout -b tmp
$ git reset HEAD~2
$ git commit -a
分支tmp的提交将与两个单独的提交相同。

或者 git rebase -i HEAD~2,并进行压缩。 - Tobu
3
哎呀,一个回答已经超过6年了还被踩了!这可真算得上是考古级别的了。留个评论解释一下会更好些。 - William Pursell
我不是那个点踩的人,但我猜可能是因为有更简单、更安全的方法来做这件事;git reset可以消除一些额外的东西。评论中提供的rebase会更安全一些,因为它至少会告诉你工作树是否有变更。话虽如此,我认为这个答案还是有价值的。 - Smar
这个答案对我很有帮助,因为我需要处理超过20个提交... - Dror Cohen
2
如果您添加了新文件/重命名文件,则这种做法是危险的。 - sdevikar

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