假设你有一个包含三次提交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是初始提交,但现在您希望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
在您有数百或数千个提交的情况下,使用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)手册页