Git 如何修改还没推到远端的提交?


#1

有的时候,某一个 commit 我写错了提交信息,还有的时候是忘了提交一些文件。该怎么修改历史提交信息/文件?假设这些提交还没有推到远端的话。


#2

修改最近一次提交的注释信息

git commit --amend

上面的命令会打开编辑器,允许你更改最近一次提交的注释。你也可以直接在命令行里指定新的提交信息:

git commit --amend -m "New commit message"

不过上面这种方式可能会不利于输入多行注释或是仅仅修改之前输入注释的一小部分。

需要注意的是本地不要有已经 staged 的改动,否则上面的命令会让他们也加入到提交里面。没有 staged 的改动不会被提交。

修改已经推到远端的提交信息

如果你已经将你的想修改的提交推到远端,可以使用如下的命令强制推送

git push <remote> <branch> --force
# Or
git push <remote> <branch> -f

注意: 强制推到远端会把本地的分支覆盖到远端分支。 如果远端分支有你本地还没有的提交,会丢失那部分提交。

注意: 谨慎修改已经共享给别人的分支的提交。 修改提交会重写提交的 SHA ID, 这将会给已经更新了你想修改提交的带来麻烦。所有已经更新到你被修改的提交的那些人都要将本地的代码和你新修改的同步,这个过程有的时候会比较难。所以当你想修改已经共享的提交历史时,注意协调其他人。或者更简单的办法是尽量避免这么做。


使用交互式 rebase

另外一个办法是使用交互式 rebase。
这种方法能让你修改任何提交的信息,不是最新的提交也可以。

// X 是你想编辑的最近提交的数量
git rebase -i HEAD~X

你可以合并提交,也可以使用 e/r 修改提交信息。

交互式 rebase 应该注意

使用 git reabse -i HEAD~X 有可能会得到多于 X 个提交。原因是 Git 会收集最后的 X 个提交,如果遇到有 merge,那么 merge 相关的提交也会被收集并显示出来。所以最终的结果可能会是 X+ 个。

高级技巧:

你可以使用 git rerere 来将你的修改扩散到多个分支并让 Git 自动解决冲突,如果有多个分支都需要改的话。


参考文档

git-commit(1) Manual Page
git-rebase(1) Manual Page
git-push(1) Manual Page