如何在Git中对第一次提交进行变基?

484

我使用git init创建了一个新的仓库,然后进行了三次提交。现在我想要变基来回到我的第一次提交并进行修改,但是如果我使用git rebase -i HEAD~3,它会显示错误-fatal: invalid upstream 'HEAD~3'

如果我尝试同样的操作,但使用HEAD~2,那么它有点起作用,但只允许我重新排列最后两个提交。

如何引用“还没有任何提交”的提交或返回并插入空提交?


git rebase -i HEAD~3的错误:

fatal: invalid upstream 'HEAD~3'  

8
可能是 Edit the root commit in Git? 的重复问题。 - Liam
检出第一个提交并修改它。 - M Imam Pratama
2个回答

840

使用最新版本的Git,可以轻松地完成此操作(这已经出现很长时间了,因此您应该已经拥有它):

简单方法是使用最近足够新的Git(现在已经发布很久了,所以你应该已经有这个):

(Two possible translations with slightly different wording, but both convey the same meaning and follow the requirements.)
git rebase -i --root

另外一个简单的方法是使用 git checkout --orphan 来设置一个新的根提交,然后将旧的提交复制到其上面。正如 twalberg 在评论中指出的那样(已被删除,但现在在 https://dev59.com/7GAg5IYBdhLWcg3w7uyk#68279810 的回答中有详细说明),这也是 rebase -i --root 内部实际执行的操作。对于一些目的,例如拆分最初的提交,此初始空提交非常有用。

未来的小贴士(2022年):通常最好让第一次提交仅包含一些样板文件,如 README。任何新的、空的仓库中的第一个提交始终有点特殊。请注意,如果您使用像 Bitbucket、GitHub 和 GitLab 这样的托管站点,在创建存储库时它们经常会为您做出这样的初始提交,以便您可以克隆因此创建的存储库并拥有一个起点。


1
使用 git rebase -i --root 命令尝试压缩第二个提交时,出现错误 error: cannot 'fixup' without a previous commit(我只想要第一个提交)。 - mikemaccana
3
你要编辑指令表中的什么内容?你应该有一个提交列表,最老的在顶部,并且每个都有“pick”命令。将第二个“pick”更改为“squash”或“fixup”,编写指令表,退出编辑器,Git 应该会完成工作。 - torek
@Jason:自从1.6.2或1.7.12版本以来,它就一直存在了(基本的“--root”是在Git 1.6.2中引入的,改进版则是在1.7.12中引入的)。你所说的“blowing up”是什么意思? - torek
喜欢这个命令。以前从来没有成功地使用过,除非修改所有后续提交的元数据。虽然我想这也可以被视为一种特性。 - vhs
1
@Jason,该消息大致意思是“错误:在没有先前提交的情况下无法进行'fixup'操作。您可以使用'git rebase --edit-todo'修复此问题,然后运行'git rebase --continue'。或者您可以使用'git rebase --abort'中止rebase操作。”。 - kleinfreund
显示剩余2条评论

23

Torek的回答 在您想要对提交的文件进行更改、编辑作者/消息等方面是可行的。但是,如果您想要拆分提交或类似操作,则很可能会遇到麻烦,因为您无法从初始提交执行git reset HEAD~命令。

要实现这一点,您可以插入一个空的初始提交,如下所示:

git checkout --orphan empty-initial-commit
git rm -r --cached .
git clean -d -f
git commit --allow-empty -m 'Empty initial commit'
git checkout <branch>
git rebase empty-initial-commit
git branch -d empty-initial-commit

然后你可以执行git rebase -i,编辑提交记录(第一个非空提交记录),并像平常一样执行git reset HEAD~

Translated text:

然后你可以执行git rebase -i,编辑提交记录(第一个非空提交记录),并像平常一样执行git reset HEAD~


tokek的答案对我添加文件很有效。你要么是错的,要么是不完整的(“或者类似的任何东西”并不包括添加/删除文件)。 - Mark Jeronimus
1
这个方法非常有效。我认为在进行空提交之前,您需要取消暂存所有文件并运行 git clean -fd 命令以确保提交是空的。 - tarekahf
很好的捡漏@tarekahf。我已经更新了命令以包含这些步骤。 - sworisbreathing
1
可以分割根提交而不必再做额外的提交,但这种方法可能更容易,因此对于大多数人来说更好。 :-)(我被最近的评论带回到这里,刚刚注意到这个答案;现在已经点赞了) - torek
1
可能由于预提交钩子的原因,此操作可能会失败。 - CervEd

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接