假设您的历史记录包含三个提交 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
有没有办法,或者这是不可能的?
答案 0 :(得分:155)
使用git rebase -i --root
从Git version 1.7.12开始。
在交互式rebase文件中,将第二行提交 B 更改为 squash ,并将其他行保留在 pick :
pick f4202da A
squash bea708e B
pick a8c6abc C
这会将两个提交 A 和 B 组合到一个提交 AB 。
在this answer中找到。
答案 1 :(得分:126)
你试过了:
git rebase -i A
如果您继续使用edit
而非squash
,则可以这样开始:
edit e97a17b B
pick asd314f C
然后运行
git reset --soft HEAD^
git commit --amend
git rebase --continue
完成。
答案 2 :(得分:64)
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
答案 3 :(得分:10)
对于交互式rebase,您必须在A之前执行此操作,以便列表为:
pick A
pick B
pick C
成为:
pick A
squash B
pick C
如果A是初始提交,则必须在A. Git考虑差异之前进行不同的初始提交,它将对(A和B)和(B和C)之间的差异起作用。因此壁球在你的例子中不起作用。
答案 4 :(得分:9)
如果您使用kostmo's answer
进行数百或数千次提交git rebase -i --root
可能不切实际且速度慢,只是由于rebase脚本必须处理两次的大量提交,一次生成交互式rebase编辑器列表(您选择要采取的操作)每次提交),并且一次实际执行提交的重新应用。
这是一个替代解决方案,它将避免因首先不使用交互式rebase 而生成交互式rebase编辑器列表的时间成本。这样,它与Charles Bailey's solution类似。您只需从第二次提交创建一个孤立分支,然后在其上面重新定义所有后代提交:
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
答案 5 :(得分:1)
在一个相关的问题中,我设法提出了一种不同的方法来解决第一次提交的问题,这是第二次提交。
如果您有兴趣:git: how to insert a commit as the first, shifting all the others?
答案 6 :(得分:0)
小队的Git命令: git rebase -i HEAD〜[提交数]
假设您的git提交历史记录如下:
pick 5152061壮举:添加了对保存图像的支持。 (一种)
pick 39c5a04修复:错误修复。 (B)
选择839c6b3修复:解决了冲突。 (C)
现在您要将A和B压榨成AB,执行以下步骤:
pick 5152061壮举:添加了对保存图像的支持。 (一种)
s 39c5a04修复:错误修复。 (B)
选择839c6b3修复:解决了冲突。 (C)
注意:对于挤压提交,我们可以使用s或s。
最终结果将是:
pick 5152061壮举:添加了对保存图像的支持。 (AB)
选择839c6b3修复:解决了冲突。 (C)
答案 7 :(得分:-1)
你必须执行一些命令行魔术。
git checkout -b a A
git checkout B <files>
git commit --amend
git checkout master
git rebase a
那应该留给你一个AB和C作为提交的分支。