我想在一个分支的中间将几个提交压缩在一起,而不修改前后的提交。
我有:
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:另外,如果可能的话,我更喜欢E
, F
和G
保持不变的解决方案(主要是关于提交日期)。
您可以进行交互式重基并手动选择要压缩的提交。这将重写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
。如果您现在完成了重置,那么您将保留每个提交的原样,这实际上是一个无操作。但是,如果您想要压缩某些中间提交,请编辑并更改列表:
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
中,仅为提交B
、C
和D
留下一次提交。其他提交保持原样。
保存文件(Windows操作系统为Git Bash时为: wq),完成重置。请记住,您可能会因此而产生合并冲突,但解决它们并没有什么特别之处,您可以像处理任何常规的重基或合并一样继续进行。
如果你在重基后检查分支,你会注意到E
、F
和G
提交现在有了新的哈希值、日期等。这是因为这些提交实际上已经被新的提交所取代。这样做的原因是您重写了历史记录,因此提交通常不能再与以前相同。