你如何使用git format-patch将提交压缩成一个补丁?

时间:2009-03-05 20:53:59

标签: git patch squash git-squash

我在一个分支上有八个提交,我想通过电子邮件发送给一些不是git开悟的人。到目前为止,我所做的每件事都给了我8个补丁文件,或者从一开始就开始给分支历史上每次提交的补丁文件。我使用git rebase --interactive来压缩提交,但是现在我尝试的所有内容从一开始就给了我数以万计的补丁。我做错了什么?

git format-patch master HEAD # yields zillions of patches, even though there's 
                             # only one commit since master

8 个答案:

答案 0 :(得分:179)

我建议在一次性分支上执行此操作,如下所示。如果您的提交位于“newlines”分支中并且您已经切换回“master”分支,那么这应该可以解决问题:

[adam@mbp2600 example (master)]$ git checkout -b tmpsquash
Switched to a new branch "tmpsquash"

[adam@mbp2600 example (tmpsquash)]$ git merge --squash newlines
Updating 4d2de39..b6768b2
Fast forward
Squash commit -- not updating HEAD
 test.txt |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

[adam@mbp2600 example (tmpsquash)]$ git commit -a -m "My squashed commits"
[tmpsquash]: created 75b0a89: "My squashed commits"
 1 files changed, 2 insertions(+), 0 deletions(-)

[adam@mbp2600 example (tmpsquash)]$ git format-patch master
0001-My-squashed-commits.patch

希望这有帮助!

答案 1 :(得分:128)

只需再添加一个解决方案: 如果你改用它:

git format-patch master --stdout > my_new_patch.diff

然后它仍然是8个补丁...但它们都将在一个补丁文件中,并将作为一个补丁:

git am < my_new_patch.diff

答案 2 :(得分:20)

我总是在你的例子中使用git diff,比如

git diff master > patch.txt

答案 3 :(得分:18)

如您所知,git format-patch -8 HEAD将为您提供八个补丁。

如果您希望8个提交显示为一个,并且不介意重写分支的历史记录(o-o-X-A-B-C-D-E-F-G-H),您可以:

git rebase -i
// squash A, B, C, D, E ,F, G into H

或者,这将是一个更好的解决方案,在新分支上重播X(8次提交前提交)的所有8次提交

git branch delivery X
git checkout delivery
git merge --squash master
git format-patch HEAD

这样,你在“delivery”分支上只有一个提交,它代表了你最近的8次提交

答案 4 :(得分:18)

这是亚当亚历山大答案的改编,以防你的变化在主分支。这样做:

  • 从我们想要的位置创建一个新的一次性分支“tmpsquash”(查找运行“git --log”或使用gitg的SHA密钥。选择你想成为tmpsquash head的提交,之后的提交主人将被压扁的提交)。
  • 合并从master到tmpsquash的更改。
  • 将压扁的变化提交给tmpsquash。
  • 使用压缩的提交创建补丁。
  • 回到主分会

laura@rune:~/example (master)$ git branch tmpsquash ba3c498878054e25afc5e22e207d62eb40ff1f38
laura@rune:~/example (master)$ git checkout tmpsquash
Switched to branch 'tmpsquash'
laura@rune:~/example (tmpsquash)$ git merge --squash master
Updating ba3c498..40386b8
Fast-forward
Squash commit -- not updating HEAD

[snip, changed files]

11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example  (tmpsquash)$ git commit -a -m "My squashed commits"
[test2 6127e5c] My squashed commits
11 files changed, 212 insertions(+), 59 deletions(-)
laura@rune:~/example  (tmpsquash)$ git format-patch master
0001-My-squashed-commits.patch
laura@rune:~/example  (tmpsquash)$ git checkout master
Switched to branch 'master'
laura@rune:~/example  (master)$

答案 5 :(得分:4)

两个标签之间的格式补丁:

git checkout <source-tag>
git checkout -b <tmpsquash>
git merge --squash <target-tag>
git commit -a -m "<message>"
git format-patch <source-tag>

答案 6 :(得分:4)

最简单的方法是使用git diff,如果您想要压缩方法输出的组合提交消息,请添加git log。例如,要在提交abcd1234之间创建补丁:

git diff abcd..1234 > patch.diff
git log abcd..1234 > patchmsg.txt

然后在应用补丁时:

git apply patch.diff
git add -A
git reset patch.diff patchmsg.txt
git commit -F patchmsg.txt

在处理非文本文件时,请忘记--binary git diff的{​​{1}}参数。图片或视频。

答案 7 :(得分:0)

基于Adam Alexander的回答:

git checkout newlines
## must be rebased to master
git checkout -b temporary
# squash the commits
git rebase -i master
git format-patch master