174

我在一个分支上有八个提交,我想通过电子邮件发送给一些还没有 git 开明的人。到目前为止,我所做的一切要么给了我 8 个补丁文件,要么从一开始就开始给我分支历史中每个提交的补丁文件。我使用 git rebase --interactive 来压缩提交,但现在我尝试的一切从一开始就给了我无数的补丁。我究竟做错了什么?

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

8 回答 8

195

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

[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
于 2009-03-05T21:46:58.997 回答
140

只是在锅中再添加一种解决方案:如果您改用它:

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

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

git am < my_new_patch.diff
于 2009-12-12T08:28:45.487 回答
23

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

git diff master > patch.txt
于 2009-03-05T22:03:20.703 回答
22

如您所知,agit 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

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

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

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

于 2009-03-05T21:46:02.150 回答
19

这是对亚当亚历山大回答的改编,以防您的更改在主分支中。执行以下操作:

  • 从我们想要的点创建一个新的一次性分支“tmpsquash”(查找运行“git --log”或使用 gitg 的 SHA 密钥。选择您想要成为 tmpsquash 头的提交,之后在 master 中的提交将是压扁的提交)。
  • 合并从 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)$
于 2010-10-17T15:52:38.423 回答
8

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

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

于 2015-09-03T10:31:39.440 回答
7

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

git checkout <source-tag>
git checkout -b <tmpsquash>
git merge --squash <target-tag>
git commit -a -m "<message>"
git format-patch <source-tag>
于 2013-09-02T11:39:16.970 回答
0

根据亚当亚历山大的回答:

git checkout newlines
## must be rebased to master
git checkout -b temporary
# squash the commits
git rebase -i master
git format-patch master
于 2012-12-30T22:25:56.557 回答