小编典典

压缩 Git 中的前两个提交?

all

你可以将git rebase --interactive <commit>任意数量的提交压缩成一个。

除非您想将提交压缩到初始提交中,否则这一切都很好。这似乎是不可能的。

有什么方法可以实现吗?


中度相关:

在一个相关的问题中,我设法提出了一种不同的方法来解决第一次提交的压缩需求,也就是说,使它成为第二次提交。


阅读 95

收藏
2022-03-04

共1个答案

小编典典

2012 年 7 月更新(git
1.7.12+

您现在可以将所有提交 rebase 到 root,并选择第二个提交Y与第一个X.

git rebase -i --root master

pick sha1 X
squash sha1 Y
pick sha1 Z
git rebase [-i] --root $tip

此命令现在可用于重写从 ” $tip” 到根提交的所有历史记录。

请参阅Chris Webb (
)在 GitHub上的提交
df5df20c1308f936ea542c86df1e9c6974168472
arachsys

如评论中所述,如果您需要在远程存储库中发布该返工,则在任何操作之后都需要一个[git push --force-with-lease--force``rebase


原始答案(2009 年 2 月)

我相信您会在 SO 问题“ 如何组合 git存储库的前两次提交? ”中找到不同的方法。

Charles Bailey在那里提供了最详细的答案,提醒我们提交是一棵完整的树(不仅仅是与以前的状态不同)。
在这里,旧提交(“初始提交”)和新提交(挤压的结果)将没有共同的祖先。
这意味着您不能commit --amend将初始提交“”转换为新的提交,然后将前一个初始提交的历史重新定位到新的初始提交(很多冲突)

(最后一句话不再适用于git rebase -i --root <aBranch>

而是(使用A原始的“初始提交”,并且B需要将后续提交压缩到初始提交中):

  1. 回到我们想要形成初始提交的最后一个提交(分离 HEAD):

     git checkout <sha1_for_B>
    
  2. 将分支指针重置为初始提交,但保持索引和工作树不变:

     git reset --soft <sha1_for_A>
    
  3. 使用“B”中的树修改初始树:

     git commit --amend
    
  4. 临时标记这个新的初始提交(或者您可以手动记住新的提交 sha1):

     git tag tmp
    
  5. 回到原来的分支(本例假设为 master):

     git checkout master
    
  6. 将 B 之后的所有提交重播到新的初始提交:

     git rebase --onto tmp <sha1_for_B>
    
  7. 删除临时标签:

     git tag -d tmp
    

这样,“ rebase --onto”不会在合并期间引入冲突,因为它会将在最后一次提交 ( ) 之后B生成的历史重新设置为要压缩到初始提交 (
)Atmp(表示压缩的新初始提交) 的历史记录:微不足道的快进仅合并。

这适用于“ A-B”,但也适用于“ A-...-...-...-B”(任何数量的提交都可以通过这种方式压缩到最初的提交中)

2022-03-04