撤销本地仓库的提交
Git撤销本地未推送的commit(git reset用法)
#tech / ops / git
#type / howto
#status / evergreen
撤销本地仓库的提交
情境
提交到本地仓库之后,推送到远程仓库之前,有想要撤销的提交,应该怎么做
这个情境是:Commit 了,但还没 Push。
这是一个非常“安全”的时刻,因为你的修改只存在于本地,撤销起来非常容易,也不会影响其他人。
以下是针对不同需求的三种解决方案:
方法
最核心的命令是 git reset。你需要根据**“你希望代码变成什么样”**来选择参数:--soft、--mixed 或 --hard。
1. 想要撤销提交,但保留所有修改(最推荐)
如果你只是觉得提交太早了,或者忘了加某个文件,想撤销 Commit 操作,但保留代码在暂存区(也就是 git add 之后的状态)。
git reset --soft HEAD^
- 结果: Commit 消失了,但你的代码都在,且处于已暂存(绿色)状态。
- 下一步: 你可以直接修改文件,然后再次
git commit。
2. 想要撤销提交,并把文件退回到工作区
如果你想连 git add 的操作也一起撤销,让文件回到未暂存(红色)的状态。
git reset --mixed HEAD^
# 或者简写为(因为 --mixed 是默认参数)
git reset HEAD^
- 结果: Commit 消失了,代码都在,但处于未暂存(红色)状态。
- 下一步: 你需要重新
git add想要的文件。
3. 【危险】想要彻底放弃这次提交的所有修改
如果你发现这次提交完全是错误的,想要彻底删除写的代码,回到上一次提交时的样子。
git reset --hard HEAD^
- 结果: Commit 消失了,你的代码修改也全部消失了。
- 警告: 这是一个破坏性操作,无法找回代码,请谨慎使用。
4. 只是想修改一下提交信息(Comment)
如果你代码没问题,只是提交说明(Message)写错了,或者漏提了一个小文件。
# 修改完漏掉的文件后(如果有的话)执行:
git add .
git commit --amend
- 结果: 不会产生新的 Commit 记录,而是直接覆盖掉刚才那次提交。
知识
为了让你更自信地使用这些命令,这里补充几个核心概念:
1. HEAD^ 是什么意思?
HEAD:指向当前分支的最新一次提交。^(或者~1):意思是“往回退一步”。- 所以
git reset HEAD^的意思就是:把当前的版本指针指向“上一次提交”。
2. 三种 Reset 模式对比表
| 模式 | 参数 | 撤销 Commit? | 撤销 Add (暂存)? | 删除代码? | 适用场景 |
|---|---|---|---|---|---|
| Soft | --soft | ✅ 是 | ❌ 否 (保留在暂存区) | ❌ 否 | 提交早了;想合并多次提交;漏了文件想补上。 |
| Mixed | (默认) | ✅ 是 | ✅ 是 (退回工作区) | ❌ 否 | 想要重新整理哪些文件该提交。 |
| Hard | --hard | ✅ 是 | ✅ 是 | ✅ 是 (高危) | 代码写烂了,想彻底重来。 |
3. 为什么说“没 Push 之前很安全”?
Git 的设计原则是:只要没有推送到远程仓库(GitHub/GitLab),本地的历史记录你可以随意修改。
一旦你 Push 了,再使用 git reset 就会导致你和远程仓库的历史不一致(你需要强制推送 git push -f),这在多人协作中是会引发冲突的。但在 Push 之前,你可以像现在这样随意“后悔”。
你是遇到了哪种情况?
- 如果是提交说明写错了,用
git commit --amend最快。 - 如果是提交了不该提交的文件,用
git reset --soft HEAD^最稳妥。
需要我进一步解释 git revert(用于已经 Push 的情况)的区别吗?