44

我想在分支中间将多个提交压缩在一起,而不需要修改之前和之后的提交。

我有 :

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:另外,如果可能的话,我更喜欢一个解决方案EF并且G保持不变(主要是关于提交日期)。

4

1 回答 1

67

您可以进行交互式变基并手动选择要压缩的提交。这将重写您的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,然后压缩CB,只留下一个提交用于提交B,CD。其他提交保持原样。

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

如果您在变基后检查分支,您会注意到EFG提交现在具有新的哈希、日期等。这是因为这些提交实际上已被新提交替换。这样做的原因是您重写了历史记录,因此一般的提交不能再与以前相同。

于 2016-08-18T16:47:54.567 回答