Git 压缩在分支中间提交
Git squash commits in the middle of a branch
我想在一个分支中间将几个提交压缩在一起,而不修改前后的提交。
我有:
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
保持不变的解决方案(主要是关于提交日期)。
您可以进行交互式变基并提交 select 您想要压缩的提交。这将重写您的 dev
分支的历史记录,但由于您尚未推送这些提交,因此除了您自己的计算机上可能发生的情况外,不应有任何负面影响。
从以下内容开始:
git checkout dev
git rebase -i HEAD~6
这应该会显示一个 window 显示以下 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 将该提交合并到 上方 的提交中,这是 之前 [=] 立即提交的提交46=]它。所以这表示将提交 D
向后压缩为提交 C
,然后将 C
压缩为 B
,只剩下一个提交 B
, C
,以及 D
。其他提交保持原样。
保存文件(:wq on Git Bash in Windows),rebase完成。请记住,您可能会像预期的那样从中得到合并冲突,但解决它们没有什么特别之处,您可以像处理任何常规变基或合并一样继续。
如果你在 rebase 之后检查分支,你会注意到 E
、F
和 G
提交现在有新的哈希值、日期等。这是因为这些提交实际上已经被新的提交所取代。这样做的原因是你重写了历史,因此一般的提交不能再和以前一样了。
我想在一个分支中间将几个提交压缩在一起,而不修改前后的提交。
我有:
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
保持不变的解决方案(主要是关于提交日期)。
您可以进行交互式变基并提交 select 您想要压缩的提交。这将重写您的 dev
分支的历史记录,但由于您尚未推送这些提交,因此除了您自己的计算机上可能发生的情况外,不应有任何负面影响。
从以下内容开始:
git checkout dev
git rebase -i HEAD~6
这应该会显示一个 window 显示以下 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 将该提交合并到 上方 的提交中,这是 之前 [=] 立即提交的提交46=]它。所以这表示将提交 D
向后压缩为提交 C
,然后将 C
压缩为 B
,只剩下一个提交 B
, C
,以及 D
。其他提交保持原样。
保存文件(:wq on Git Bash in Windows),rebase完成。请记住,您可能会像预期的那样从中得到合并冲突,但解决它们没有什么特别之处,您可以像处理任何常规变基或合并一样继续。
如果你在 rebase 之后检查分支,你会注意到 E
、F
和 G
提交现在有新的哈希值、日期等。这是因为这些提交实际上已经被新的提交所取代。这样做的原因是你重写了历史,因此一般的提交不能再和以前一样了。