世上还是有后悔药 - git reset
如果你想 **取消上一次的 git commit
**,可以根据具体情况使用不同的方法:
1. 仅撤销 commit(保留修改)
如果你只想 撤销 commit 但保留文件的修改(即回到 git commit
之前的状态):
1 | git reset --soft HEAD~ |
--soft
选项会 保留你的修改,只是撤销了 commit 记录,相当于回到了git add
之后但还没commit
的状态。
2. 撤销 commit 并取消 git add
如果你还想 **同时取消 git add
**,让所有文件恢复为未暂存(unstaged)的状态:
1 | git reset HEAD~ |
- 这会撤销 commit,并且将已经
git add
的文件放回未暂存状态。
3. 彻底撤销 commit 并删除修改
如果你想 完全撤销 commit 并丢弃所有修改:
1 | git reset --hard HEAD~ |
- 这个操作是不可逆的,会删除所有的未推送的修改,谨慎使用!
4. 如果 commit 已经推送到远程仓库
如果 commit 已经被推送到远程仓库(如 GitHub、GitLab),git reset
只是本地生效,远程不会变化。此时需要强制推送:
1 | git reset --soft HEAD~ |
警告:
git push -f
会重写远程仓库的提交记录,可能影响其他开发者,谨慎使用!
5. 使用 git revert
(安全方式)
如果 commit 已推送,并且你不希望使用 git push -f
强制覆盖历史,推荐使用 git revert
:
1 | git revert HEAD |
- 这会创建一个新的 commit 来撤销上一次提交,而不会改变历史记录(适用于多人协作的情况)。
总结如下
操作 | 影响 |
---|---|
git reset --soft HEAD~ |
仅撤销 commit,保留所有修改(回到 git add 之后的状态) |
git reset HEAD~ |
撤销 commit,并取消 git add (回到 git status 可见的未暂存状态) |
git reset --hard HEAD~ |
彻底删除 commit 和修改(谨慎使用!) |
git revert HEAD |
创建一个新的 commit 来撤销上一次提交(安全方式,适用于已推送的 commit) |
git push origin -f |
强制推送修改后的提交历史(危险操作,谨慎使用) |
如果你不确定哪种方式适合你的情况,可以先运行 git status
看看当前状态,然后选择合适的操作。
使用 git reset HEAD <file>...
来取消暂存。 所以,我们可以这样来取消暂存 CONTRIBUTING.md
文件:
1 | git reset HEAD CONTRIBUTING.md |
这个命令有点儿奇怪,但是起作用了。 CONTRIBUTING.md
文件已经是修改未暂存的状态了。
git reset
确实是个危险的命令,如果加上了--hard
选项则更是如此。 然而在上述场景中,工作目录中的文件尚未修改,因此相对安全一些。