git交互式rebase压缩到下一次提交

时间:2017-05-26 22:09:15

标签: git squash git-squash git-interactive-rebase

在Git中我可以使用交互式rebase来重写历史记录,这很棒,因为在我的功能分支中,我使用部分工作代码进行了大量提交,因为我探索了不同的重构和完成它的方法。

我想在重新定位或将分支合并到主服务器之前将大量提交压缩在一起。

从第一个(顶部)到底部(最后一个)按顺序编写了一些提交

1. Initial commit on feature branch "Automatic coffee maker UI"
2. Add hot chocolate as product
3. Add tea as product. Products are now generic
4. Create in memory data store for adapter tests
5. Cry because I can't get entity framework to create a composite key. Integration tests broken.
6. Implemented composite key!!
7. All tests green and feature done!

假设我想继续提交3,4和7。

使用rebase我想“压缩”提交

  • 1和2进入3。
  • 4次
  • 5和6进入7

理想情况在交互式rebase中我会做

1. squash
2. squash
3. pick (contains the work of 1 & 2)
4. pick 
5. squash
6. squash
7. pick (contains the work of 5 & 6)

但这是倒退,因为squash将提交与其先前的提交合并。我无法弄清楚如何让它向前挤压。

我是否很难,我是否应该接受不起作用(我宁愿让它工作),还是有办法实现这个目标?

我正在使用

调用此命令
git checkout My-feature-branch
git rebase master -i

然后我正在编辑出现的提交列表,并尝试通过保存文件和编辑编辑器来完成它,这通常适用于我。

4 个答案:

答案 0 :(得分:4)

如果可行的话,您还需要对提交进行重新排序,以便在要进行压缩的提交之前进行提交。

如果这是不可行的,因为你会遇到你不想解决的冲突,只需要解决它

1. pick
2. squash
3. squash
4. pick 
5. pick
6. squash
7. squash

当南瓜完成后,您可以编辑提交消息以包含您希望最终提交的消息。非常简单。 : - )

你甚至可以做到

1. pick
2. fixup
3. squash
4. pick 
5. pick
6. fixup
7. squash

然后我认为应该只提交一次提交消息编辑器,就像使用fixup一样,只需在不启动编辑器的情况下获取上一个提交消息。

当提交消息编辑器触发时,你还会获得两个提交消息,即要被压缩的提交消息和要被压缩的提交消息,这样你就可以简单地删除你提交的提交消息#39;我想保留。

答案 1 :(得分:2)

Vampire's answer是对的,但我想提供一个不同的视角。我认为这是你让自己比必要更多的结果:你从:

开始
  

假设我想继续提交3,4和7。

然后添加:

  
      
  • 1和2进入3。
  •   
  • 4次
  •   
  • 5和6进入7
  •   

但这意味着您要保留(em,所有)所有的内容(1,2,3,4,5,6和7)...而不是单独的提交< / em>的。交互式rebase squash并不意味着“扔掉”,甚至“扔掉提交消息”,它只是意味着“结合”。如果动词是“组合”或“融合”或“混入”或某些此类动词可能会更好。因此,序列(选择,壁球,壁球)意味着:保留所有三个,同时按顺序应用它们,然后从中进行一次大的提交。

正如已经指出的那样,一旦Git进行了一次大的提交,Git会给你另一个机会将三个组合的提交消息编辑成一个大的提交消息。

当rebase完成后,你没有保留原始提交的任何。相反,您已经进行了 new 提交。准确地说,新的第一次提交是如何从部分组合的,只是最终的源是什么,以及你在一个大的提交消息中放入了什么并不重要。

答案 2 :(得分:2)

确实可以在交互式 rebase 期间将提交压缩到 后续 提交中,并完全保留这些提交中第二个提交的身份(包括作者、日期等)。

然而,该方法有些复杂,因此 git rebase -i 的本机支持仍然会受到赞赏。

我将仅通过三个提交 aaaaaaa Abbbbbbb Bccccccc C 进行演示,我们希望将 A 折叠为 B 并保留 {{1 }} 的身份:(该方法很容易推广到更多提交)

  • B
  • 修改编辑脚本以在提交git rebase -i aaaaaaa^后停止并退出编辑器:
    B
  • 当变基在 pick aaaaaaa A edit bbbbbbb B pick ccccccc C 后停止时,恢复最新提交 两次,然后继续:
    B
    因为恢复还原会恢复以前的状态,所以所有后续提交都将干净利落地应用。 git revert HEAD git revert HEAD git rebase --continue B 的顺序没有任何影响,但是这些提交中的第一个带有提交 B 的完整标识(实际上,在这个阶段它仍然提交Revert "B")。
    BB 可以合并在一起形成一个 no-op 提交,携带提交 B 的身份并带有单独的 Revert "B"。这非常有用,推荐用于防止虚假合并冲突,尤其是在更复杂的情况下。然而,我们将在这里跳过这一步,只将提交保持在一起。
    现在重要的提交是 rebase -i --keep-empty aaaaaaa^,它将携带最初由 Revert "Revert "B"" 所做的所有更改。
  • 现在再次B移动rebase -i aaaaaaa^经过AB,同时挤压Revert "B"B和{{1} }:
    Revert "B"
    由于 Apick bbbbbbb B squash b111111 Revert "B" squash a222222 A squash b333333 Revert "Revert "B"" pick c444444 C 的序列没有任何影响,因此您可以将任何提交移过它,同时只会创建可解决的合并冲突。
  • 当 rebase 因合并冲突而停止时,将 B 与可以自动解决琐碎冲突的工具一起使用,并让这些工具做到这一点。
  • Rebase 将再次停止,让您编辑压缩提交的提交消息。根据您的喜好进行编辑。
  • Revert "B" 大功告成。

答案 3 :(得分:0)

您想要的是:

1. pick
2. squash
3. fixup
4. pick
5. squash
6. squash
7. fixup

然后,当新的合并提交出现在编辑器中时,删除所选提交的行并保留修订。这样产生的功能补丁应该具有该系列中最后一次提交的提交消息。