结合Git存储库的前两个提交?

时间:2009-01-12 14:53:21

标签: git rebase git-rebase git-rewrite-history

假设您的历史记录包含三个提交 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

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

8 个答案:

答案 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作为提交的分支。