Git壁球在分支中间提交

dea*_*eef 29 git git-squash

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

我有 :

A -- B -- C -- D -- E -- F -- G
|                             |
master                        dev
origin/master
Run Code Online (Sandbox Code Playgroud)

我想把它压成

A -- H -- E -- F -- G
|                   |
master              dev
origin/master
Run Code Online (Sandbox Code Playgroud)

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

我怎样才能做到这一点 ?

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

PPS:另外,如果可能的话,我更喜欢一个解决方案E,F并且G保持不变(主要是关于提交日期).

Tim*_*sen 39

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

从以下开始:

git checkout dev
git rebase -i HEAD~6
Run Code Online (Sandbox Code Playgroud)

这将显示一个窗口,显示以下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
Run Code Online (Sandbox Code Playgroud)

显示的第一个提交(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
Run Code Online (Sandbox Code Playgroud)

请仔细注意上面发生的事情.通过键入squash你告诉Git将该提交合并到它上面的那个,这是它之前的提交.因此,这说壁球犯D倒退到提交C,然后压扁CB,让你只用一个提交的提交B,CD.其他提交保持不变.

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

如果底垫后检查的分支,你会发现E,FG犯下现在有了新的哈希值,日期等,这是因为这些提交实际上已经换成新的提交.这样做的原因是你重写了历史,因此一般的提交不再像以前一样.

  • 像魅力一样工作,谢谢!我没想到这会那么容易。但是,有没有一种方法可以在不重写最后3个提交的情况下做同样的事情?我注意到git创建了3个新提交(提交日期为当前日期)。 (3认同)
  • 在谷歌上找到它。我在第一次 rebase 上尝试过,但没有用。但是我运行它之后它改变了所有提交*在`commit_sha`之后*。所以在我的情况下,做`git rebase --committer-date-is-author-date sha_of_H` 做了我想要的。 (2认同)