假设你有一个包含三次提交a, B和C的历史记录:

A-B-C

我想将两次提交A和B合并为一次提交AB:

AB-C

我试着

git rebase -i A

打开我的编辑器,显示以下内容:

pick e97a17b B
pick asd314f C

我把这个改成

squash e97a17b B
pick asd314f C

然后Git 1.6.0.4说:

Cannot 'squash' without a previous commit

有办法吗,还是根本不可能?


在交互变基的情况下,你必须在A之前这样做,这样列表将是:

pick A
pick B
pick C

成为:

pick A
squash B
pick C

如果A是初始提交,你必须在A之前有一个不同的初始提交。Git考虑差异,它将处理(A和B)和(B和C)之间的差异。因此,在你的例子中,squash不起作用。


您必须执行一些命令行魔法。

git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a

这将为您留下一个具有AB和C作为提交的分支。


A是初始提交,但现在您希望B是初始提交。Git提交是一棵完整的树,而不是差异,即使它们通常是根据它们引入的差异来描述和查看的。

即使在A和B之间、B和C之间有多次提交,这个方法也有效。

# Go back to the last commit that we want
# to form the initial commit (detach HEAD)
git checkout <sha1_for_B>

# reset the branch pointer to the initial commit,
# but leaving the index and working tree intact.
git reset --soft <sha1_for_A>

# amend the initial tree using the tree from 'B'
git commit --amend

# temporarily tag this new initial commit
# (or you could remember the new commit sha1 manually)
git tag tmp

# go back to the original branch (assume master for this example)
git checkout master

# Replay all the commits after B onto the new initial commit
git rebase --onto tmp <sha1_for_B>

# remove the temporary tag
git tag -d tmp

你试过:

git rebase -i A

如果你继续使用edit而不是squash,就可以像这样开始:

edit e97a17b B
pick asd314f C

然后运行

git reset --soft HEAD^
git commit --amend
git rebase --continue

完成了。


在一个相关的问题中,我设法提出了一种不同的方法来满足压缩第一次提交的需要,也就是将其作为第二次提交。

如果你感兴趣:git:如何插入一个提交作为第一个,转移所有其他?


使用git rebase -i——root Git版本1.7.12。

在交互式的rebase文件中,将commit B的第二行更改为squash,其他行保留为pick:

pick f4202da A
squash bea708e B
pick a8c6abc C

这将把两次提交A和B合并为一次提交AB。

在这个答案中找到。


在您有数百或数千个提交的情况下,使用kostmo的答案

git rebase -i --root

可能不切实际且速度缓慢,这只是因为重基脚本必须处理两次大量的提交,一次生成交互式的重基编辑器列表(在其中您可以选择为每次提交采取什么操作),一次实际执行提交的重新应用程序。

下面是一种替代解决方案,它将避免生成交互式重基编辑器列表的时间成本,因为它一开始就不使用交互式重基。在这方面,它与查尔斯·贝利的解决方案相似。你只需要从第二次提交中创建一个孤儿分支,然后在它之上重新设置所有的后代提交:

git checkout --orphan orphan <second-commit-sha>
git commit -m "Enter a commit message for the new root commit"
git rebase --onto orphan <second-commit-sha> master

文档

git-checkout(1)手册 git-rebase(1)手册页


Git小队指令: git rebase -i HEAD~[提交的数量]

假设你有以下git提交历史:

pick 5152061专长:增加了保存图像的支持。(一) pick 39c5a04修复:bug修复。(B) 选择839c6b3修复:冲突已解决。(C)

现在你想把A和B压缩到AB,执行以下步骤:

pick 5152061专长:增加了保存图像的支持。(一) s 39c5a04修复:bug修复。(B) 选择839c6b3修复:冲突已解决。(C)

注意:对于压缩提交,我们可以使用squash或s。 最终结果将是: pick 5152061专长:增加了保存图像的支持。(AB) 选择839c6b3修复:冲突已解决。(C)