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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/616556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-10 06:14:31  来源:igfitidea点击:

How do you squash commits into one patch with git format-patch?

gitpatchsquashgit-squash

提问by skiphoppy

I've got eight commits on a branch that I'd like to email to some people who aren't git enlightened, yet. So far, everything I do either gives me 8 patch files, or starts giving me patch files for every commit in the branch's history, since the beginning of time. I used git rebase --interactive to squash the commits, but now everything I try gives me zillions of patches from the beginning of time. What am I doing wrong?

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

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

回答by Adam Alexander

I'd recommend doing this on a throwaway branch as follows. If your commits are in the "newlines" branch and you have switched back to your "master" branch already, this should do the trick:

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

[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

Hope this helps!

希望这可以帮助!

回答by Taryn East

Just to add one more solution to the pot: If you use this instead:

只是向锅中添加另一种解决方案:如果您使用它:

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

Then it will still be 8 patches... but they'll all be in a single patchfile and will apply as one with:

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

git am < my_new_patch.diff

回答by Rob Di Marco

I always use git diff so in your example, something like

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

git diff master > patch.txt

回答by VonC

As you already know, a git format-patch -8 HEADwill give you eight patches.

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

If you want your 8 commits appear as one, and do not mind rewriting the history of your branch (o-o-X-A-B-C-D-E-F-G-H), you could :

如果您希望您的 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

or, and it would be a better solution, replay all your 8 commits from X(the commit before your 8 commits) on a new branch

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

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

That way, you only have one commit on the "delivery" branch, and it represent all your last 8 commits

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

回答by rec

This is an adaptation of Adam Alexander answer, in case your changes are in master branch. This do the following:

这是对 Adam Alexander 回答的改编,以防您的更改在 master 分支中。这执行以下操作:

  • Creates a new throwaway branch "tmpsquash" from the point we want (look for the SHA key running "git --log" or with gitg. Select the commit you want to be tmpsquash head, the commits that are after that in master will be the squashed commits).
  • Merges the changes from master to tmpsquash.
  • Commits the squashed changes to tmpsquash.
  • Creates the patch with the squashed commits.
  • Goes back to master branch
  • 从我们想要的点创建一个新的一次性分支“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)$

回答by kashesandr

Format-patch between two tags:

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

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

回答by woojoo666

Easiest way is to use git diff, and add in git logif you want the combined commit message that the squash method would output. For example, to create the patch between commit abcdand 1234:

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

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

Then when applying the patch:

然后在应用补丁时:

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

Don't forget the --binaryargument to git diffwhen dealing with non-text files, e.g. images or videos.

不要忘记处理非文本文件时的--binary论点git diff,例如图像或视频。

回答by Julien W

Based on Adam Alexander's answer:

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

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