git reset 完整详解
git reset 的三种模式、适用场景、注意事项与常见误区
git reset 完整详解
git reset 完整详解
1
git reset [--soft | --mixed | --hard] 目标提交
HEAD:当前分支最新提交
索引区(stage):暂存区
工作区:本地磁盘中的文件内容
先看结论:三种模式的区别
| 模式 | 影响范围 | 提交是否删除 | 暂存区 | 工作区 | 适用场景 |
|---|---|---|---|---|---|
--soft | 仅移动 HEAD | 是 | 保留 | 保留 | 修改提交信息 / 重写提交 |
--mixed | 移动 HEAD + 清空暂存区 | 是 | 清空 | 保留 | 重新挑选文件再提交 |
--hard | 彻底回退 | 是 | 清空 | 清空 | 彻底放弃最近改动 |
1. --soft 软重置 ⭐ 最轻
移动 HEAD,删除提交;暂存区和工作区中的文件都保持不动
1
git reset --soft HEAD~1
- 撤销最近 1 次 commit,代码还停留在暂存区,可以直接继续修改后重新提交
.git体积不会立刻变小,因为旧提交对象还在 Git 对象数据库中- 只是在“提交历史”上回退了一步,改动还在本地等待重新提交
适用:写错 commit 信息、想重新提交前再整理内容。
2. --mixed(默认行为,不加参数就是它)
移动 HEAD,删除 commit;清空暂存区;工作区保持不变
1
2
3
# 两条命令等价
git reset HEAD~1
git reset --mixed HEAD~1
- 提交被撤销了,但文件内容还保留在工作目录中
- 之前
git add的内容会从暂存区退回,需要重新执行git add - 这是最常见、最实用的回退方式
适用:撤销提交后,想重新挑选哪些文件进入下一次提交。
3. --hard 硬重置 ⚠️ 危险
移动 HEAD;提交、暂存区、本地未提交修改全部清空,代码直接丢失
1
git reset --hard HEAD~1
⚠️ 这会直接抹掉所有未提交修改,除非你提前做了 stash 或者能从 reflog 中找回。
对于单人开发,可能是快速“回到过去”的方式;但在多人协作时,切记不要滥用。
适用:彻底抛弃最近几次提交,不再保留这些改动。
reset 之后,.git 文件夹不会立刻变小
很多人执行完 git reset --hard 后,会发现 .git 的占用空间并没有马上减少。
原因:Git 还没有真正回收旧提交对象,而是先把它们留在 reflog 中,等待垃圾回收。
如果你确认历史已经不需要,可以手动清理:
1
2
git reflog expire --expire=now --all
git gc --prune=now --aggressive
这一步会强制清理已经失效的对象,让 .git 体积真正缩小。
远程仓库怎么办
1
2
# 强制推送覆盖远程(多人协作仓库禁止!!)
git push -f origin main
多人项目里,优先考虑
git revert,不要轻易使用reset --hard去覆盖别人已经推送的提交。
如果你只是想“回退一个已提交的错误版本”,通常更稳妥的方式是:
1
git revert HEAD
这样不会直接改写历史,而是新增一个反向提交,团队协作时更安全。
一张图理解三种模式
1
2
3
4
5
6
7
HEAD
↓
提交记录
--soft : 只移动 HEAD,改动停留在暂存区
--mixed : 移动 HEAD,并清空暂存区,改动回到工作区
--hard : 移动 HEAD,并抹掉暂存区与工作区中的改动
最后总结
--soft:最安全,适合继续完善提交--mixed:最常用,适合重做提交内容--hard:最危险,适合彻底放弃修改
如果你是在写作业、修复 Bug,或者重写提交时,最推荐先用 --mixed、再根据需要决定是否 --soft/--hard。
本文由作者按照 CC BY 4.0 进行授权