Git squash在分支中间提交

时间:2016-08-18 16:35:20

标签: git git-squash

我想在分支中间将几个提交压缩在一起而不修改提前和提交的提交。

我有:

A -- B -- C -- D -- E -- F -- G
|                             |
master                        dev
origin/master

我想把它压成

A -- H -- E -- F -- G
|                   |
master              dev
origin/master

H等同于B -- C -- D。我希望能够指定H的提交消息。 A是最后一次提交的提交,因此所有提交之后都可以重写,而不会弄乱服务器。我的想法是在快进master之前清理历史。

我该怎么做?

PS:请注意,在我的情况下,我实际上有超过3次提交在中间压缩,但如果我能用3做,我应该可以用更多。

PPS:另外,如果可能的话,我更倾向于EFG保持不变的解决方案(主要是关于提交日期)。

1 个答案:

答案 0 :(得分:31)

您可以执行交互式rebase并手动选择要压缩的提交。这将重写dev分支的历史记录,但由于您没有推送这些提交,除了您自己的计算机上可能发生的事情之外,不应该有任何负面的后果。

从以下开始:

git checkout dev
git rebase -i HEAD~6

这会显示一个窗口,显示以下7个提交列表,从dev分支的HEAD返回6个步骤:

pick 07c5abd message for commit A
pick dl398cn message for commit B
pick 93nmcdu message for commit C
pick lst28e4 message for commit D
pick 398nmol message for commit E
pick 9kml38d message for commit F
pick 02jmdmp message for commit G

显示的第一个提交(上面的A)是最旧的,最后一个是最新的。您可以看到,默认情况下,每个提交的选项为pick。如果你现在完成了rebase,你只需保留每个提交,这实际上是一个无操作。但是既然你想要压缩某些中间提交,请编辑并将列表更改为:

pick 07c5abd message for commit A
pick dl398cn new commit message for "H" goes here
squash 93nmcdu message for commit C
squash lst28e4 message for commit D
pick 398nmol message for commit E
pick 9kml38d message for commit F
pick 02jmdmp message for commit G

请仔细注意上面发生的事情。通过键入squash,您告诉Git将该提交合并到上面的中,这是之前的提交。所以这就是将提交D向后压缩到提交C,然后将C压缩到B,只留下一次提交BCD。其他提交保持不变。

在Windows中的Git Bash上保存文件(:wq ),并且rebase已完成。请记住,您可以像预期的那样从中获得合并冲突,但解决它们并没有什么特别之处,您可以像任何常规的rebase或合并那样继续进行。

如果您在rebase之后检查分支,您会注意到EFG提交现在有新的哈希值,日期等。这是因为这些提交实际上已被新的提交所取代。这样做的原因是你重写了历史,因此一般的提交不再像以前一样。