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

发布于 2024-07-14 18:53:11 字数 377 浏览 13 评论 0原文

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

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

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?

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

甚是思念 2024-07-21 18:53:11

我建议在一次性分支上执行此操作,如下所示。 如果您的提交位于“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

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
爱本泡沫多脆弱 2024-07-21 18:53:11

只是为了向锅中添加另一种解决方案:
如果你改用这个:

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

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

git am < my_new_patch.diff

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:

git am < my_new_patch.diff
陌上芳菲 2024-07-21 18:53:11

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

git diff master > patch.txt

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

git diff master > patch.txt
蒗幽 2024-07-21 18:53:11

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

如果您希望 8 个提交显示为一个,并且不介意重写分支的历史记录 (ooXABCDEFGH),您可以:

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 次提交

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

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 :

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

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

浮华 2024-07-21 18:53:11

这是 Adam Alexander 答案的改编,以防您的更改发生在主分支中。 执行以下操作:

  • 从我们想要的点创建一个新的一次性分支“tmpsquash”(查找运行“git --log”或使用 gitg 的 SHA 密钥。选择您想要作为 tmpsquash 头的提交,即之后的提交在 master 中将是压缩的提交)。
  • 合并从 master 到 tmpsquash 的更改。
  • 将压缩的更改提交给 tmpsquash。
  • 使用压缩的提交创建补丁。
  • 返回master分支

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)$

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

  • 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

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)$
梦途 2024-07-21 18:53:11

最简单的方法是使用 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

不要忘记 --binary 参数git diff 处理非文本文件(例如图像或视频)时。

Easiest way is to use git diff, and add in git log if you want the combined commit message that the squash method would output. For example, to create the patch between commit abcd and 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 --binary argument to git diff when dealing with non-text files, e.g. images or videos.

谁的年少不轻狂 2024-07-21 18:53:11

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

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

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>
傲鸠 2024-07-21 18:53:11

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

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

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
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文