合并Git存储库的前两次提交?

合并Git存储库的前两次提交?,git,rebase,git-rebase,git-rewrite-history,Git,Rebase,Git Rebase,Git Rewrite History,假设您有一个包含三个提交a、B和C的历史记录: 我想将两个提交A和B合并为一个提交AB: 我试过了 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 有没有办法,或者这是不可能的?如果是交互式重基,您必须在 pick

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

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

我试过了

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

有没有办法,或者这是不可能的?

如果是交互式重基,您必须在

pick A
pick B
pick C
成为:

pick A
squash B
pick C

如果A是初始提交,那么在A之前必须有一个不同的初始提交。Git考虑差异,它将处理A和B以及B和C之间的差异。因此,挤压在您的示例中不起作用。

您必须执行一些命令行魔术

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之间存在多个提交,此配方仍然有效

回到我们想要的最后一次承诺 形成初始提交分离头 git签出 将分支指针重置为初始提交, 但保留索引和工作树不变。 git重置-软 使用“B”中的树修改初始树 git提交-修改 临时标记此新的初始提交 或者您可以手动记住新的commit sha1 git标签tmp 对于本例,返回到原始分支假定主节点 切换到主分支 将B之后的所有提交重放到新的初始提交上 git-rebase-on-tmp 移除临时标记 git标签-dtmp 你试过:

git rebase -i A
如果继续使用“编辑”而不是“挤压”,则可以这样开始:

然后跑

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

完成。

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

如果您感兴趣:

使用git-rebase-i-root 从吉特开始

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

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


可在中找到。

如果您有数百或数千次提交,请使用

这可能是不切实际和缓慢的,这是因为rebase脚本必须两次处理大量提交,一次生成交互式rebase编辑器列表,在其中选择每次提交要采取的操作,一次实际执行提交的重新应用

下面是一个替代解决方案,它可以通过首先不使用交互式基准来避免生成交互式基准编辑器列表的时间成本。在这方面,它类似于。您只需从第二次提交创建一个孤立分支,然后在其上重新设置所有子体提交的基础:

git签出-孤立-孤立 git commit-m输入新根提交的提交消息 git rebase-转到孤立主机 文档 Git小队指挥部: git-rebase-i头~[提交次数]

假设您有以下git提交历史记录:

选择5152061专长:增加了对保存图像的支持。A. 选择39c5a04修复:错误修复。B 选择839c6b3修复:冲突已解决。C

现在要将A和B挤压到AB,请执行以下步骤:

选择5152061专长:增加了对保存图像的支持。A. s 39c5a04修复:错误修复。B 选择839c6b3修复:冲突已解决。C

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

因为新旧初始提交没有共同的祖先,所以当git试图将master的整个历史应用到一个上时,可能会遇到一些不必要的冲突,即使它们有一个共同的树。通过使用-to选项对git重新设置基础,您可以告诉git开始应用的正确位置。如果您这样做是为了安静地修复github gist,则必须在提交中添加-m initial-git rebase-abort重新开始并以正确的方式执行,不挤压编辑器中的第一个提交,如果在这里重复答案会更好吗?我不确定。另请参见:。另请参见:。当我在tmp上进行git再基础时,这会触发一个大规模的交互式再基础。考虑到我有一个全新的回购协议,只有两个承诺,我想将其合并为一个,这对我来说非常有效。谢谢你@CB Bailey
git rebase -i A
edit e97a17b B
pick asd314f C
git reset --soft HEAD^
git commit --amend
git rebase --continue
pick f4202da A
squash bea708e B
pick a8c6abc C
git rebase -i --root