如何使用 git 格式补丁压缩提交到一个补丁中?

我已经在一个分支上提交了8个提交,我想通过电子邮件发送给一些还没有开窍的人。到目前为止,我所做的每件事要么给我8个补丁文件,要么开始为分支历史上的每次提交提供补丁文件,从一开始就是这样。我使用 git rebase ——交互式来压缩提交,但是现在我尝试的所有东西从一开始就给了我无数的补丁。我做错了什么?

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

正如你已经知道的,一个 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

这样,您在“交付”分支上只有一个提交,并且它代表您最近的8次提交

我建议像下面这样在一次性分支上执行此操作。如果您的提交在“ 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

我总是使用 git diff,所以在您的示例中,类似于

git diff master > patch.txt

再补充一个解决方案: 如果你用这个代替:

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

然后它仍然是8个补丁... 但它们都将在一个单一的补丁文件,并将适用于:

git am < my_new_patch.diff

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

  • 从我们需要的位置创建一个新的一次性分支“ tmpsquash”(查找运行“ git —— log”或使用 gitg 的 SHA 键)。选择你想成为 tmpsquash head 的提交,之后在 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)$

基于亚当 · 亚历山大的回答:

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

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

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

最简单的方法是使用 git diff,如果您希望使用 squash 方法输出的组合提交消息,则添加 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

在处理非文本文件(如图像或视频)时,不要忘记 --binarygit diff的参数。