如何压缩两个非连续的提交?
我对 git 中的整个变基功能有点陌生。假设我进行了以下提交:
A -> B -> C -> D
之后,我意识到 D
包含一个修复程序,该修复程序依赖于 A
中添加的一些新代码,并且这些提交属于一起。如何挤压 A
& D
在一起,留下 B
&单独使用C
?
I'm a bit new to the whole rebasing feature within git. Let's say that I made the following commits:
A -> B -> C -> D
Afterwards, I realize that D
contains a fix which depends on some new code added in A
, and that these commits belong together. How do I squash A
& D
together and leave B
& C
alone?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
您可以运行 git rebase --interactive 并将 D 重新排序在 B 之前,并将 D 压缩到 A 中。Git
将打开一个编辑器,您会看到这样的文件,例如: git rebase --interactive HEAD~4
现在您更改文件,如下所示:
git 现在会将 A 和 D 的更改合并到一个提交中,然后将 B 和 C 放入其中。当您不想保留 D 的提交消息时,可以使用
fixup
关键字来代替squash
。有关fixup
的更多信息,您可以查阅git rebase
文档,或查看You can run
git rebase --interactive
and reorder D before B and squash D into A.Git will open an editor, and you see a file like this, ex:
git rebase --interactive HEAD~4
Now you change the file that it looks like this:
And git will now meld the changes of A and D together into one commit, and put B and C afterwards. When you don't want to keep the commit message of D, instead of
squash
, you would use thefixup
keyword. For more onfixup
, you can consult thegit rebase
docs, or check out this question which has some good answers.注意:您不应该以任何方式更改已推送到另一个存储库的提交,除非您知道后果。
git log --oneline -4
git rebase --interactive
输入
i
(将 VIM 置于插入模式)将列表更改为如下所示(您不必删除或包含提交消息)。 不要拼错
squash
!:输入 Esc,然后输入
ZZ
(保存并退出 VIM)输入
i< /code>
将文本更改为您希望新提交消息的样子。我建议这是提交
A
和D
中更改的描述:键入 Esc,然后键入
ZZ
git log --oneline -4
git show E
您现在已经创建了一个新的提交
E
。提交A
和D
不再出现在您的历史记录中,但并未消失。此时您仍然可以通过 git rebase --hard D 暂时恢复它们(git rebase --hard 会破坏任何本地更改!
) em>)。Note: You should not change commits that have been pushed to another repo in any way unless you know the consequences.
git log --oneline -4
git rebase --interactive
Type
i
(Put VIM in insert mode)Change the list to look like this (You don't have to remove or include the commit message). Do not misspell
squash
!:Type Esc then
ZZ
(Save and exit VIM)Type
i
Change the text to what you want the new commit message to look like. I recommend this be a description of the changes in commit
A
andD
:Type Esc then
ZZ
git log --oneline -4
git show E
You have now created a new commit
E
. CommitsA
andD
are no longer in your history but are not gone. You can still recover them at this point and for a while bygit rebase --hard D
(git rebase --hard
will destroy any local changes!).对于使用 SourceTree 的用户:
确保您尚未推送提交。
与上一个提交压缩
For those using SourceTree:
Make sure you haven't already pushed the commits.
Squash with previous
交互式变基工作得很好,直到您拥有具有 20-30 次提交和/或来自 master 的几次合并的大型功能分支或/并在您的分支中提交时修复冲突。即使通过历史记录查找我的提交并将
pick
替换为squash
在这里也不起作用。所以我正在寻找另一种方法,发现了这个 文章。我做了我的更改以在单独的分支上进行此操作:
在此之前,我收到了大约 30 次提交的拉取请求,其中来自 master 的 2-3 次合并 + 修复冲突。在此之后,我通过一次提交就获得了明确的 PR。
PS 这里是 bash 脚本 来执行此步骤自动模式。
Interactive rebase works well until you have big feature branch with 20-30 commits and/or couple of merges from master or/and fixing conflicts while you was commiting in your branch. Even with finding my commits through history and replacing
pick
withsquash
doesn't worked here. So i was looking for another way and found this article.I did my changes to work this on separate branch:
Before this I got my pull request with about ~30 commits with 2-3 merges from master + fixing conflicts. And after this I got clear PR with one commit.
P.S. here is bash script to do this steps in automode.
$ git checkout master
$ git log --oneline
$ git rebase --onto HEAD^^^ HEAD^
$ git log --oneline
$ git checkout master
$ git log --oneline
$ git rebase --onto HEAD^^^ HEAD^
$ git log --oneline