git reset 的 soft、mixed、hard 三种模式怎么选

git reset 三种模式:--soft 只移动引用(保留原暂存区和工作区),--mixed(默认)同时重置暂存区(改动留在工作区),--hard 重置索引及跟踪文件,可能删除阻挡写入的未跟踪路径。撤销提交用 soft/mixed,丢弃代码才用 --hard。

最佳实践
Git 提交历史与版本恢复示意

三种模式的区别就在于"撤销提交后,改动去哪":--soft 只移动引用,保持暂存区和工作区不变;--mixed(默认)改动回到工作区;--hard 重置索引和跟踪文件,丢弃相应未提交改动,并可能删除阻挡写入的未跟踪路径;不是删除所有未跟踪文件。记忆口诀:soft 最温柔只动指针,hard 最粗暴全丢,mixed 居中。

下面按当前分支有父提交、工作区和暂存区原本干净的情形说明;已有暂存/未暂存改动时,soft 不会自动只留下最后一个提交的补丁。根提交没有 HEAD~1,游离 HEAD 和带路径的 reset 也有不同作用域。

图解

提交历史:  A---B---C(HEAD)
工作区/暂存区: 与 C 快照一致、无未提交改动

git reset --soft HEAD~1   → 分支指向 B,C 的改动在暂存区(git commit 直接重提)
git reset --mixed HEAD~1  → 分支指向 B,C 的改动在工作区(未暂存)
git reset --hard HEAD~1   → 分支指向 B,改动彻底消失

各模式的典型场景

# --soft:刚提交就想重做这个提交(换信息/增删文件)
git reset --soft HEAD~1 && git commit -m "更好的信息"

# --mixed:想把已提交的内容拆成多个小提交
git reset HEAD~1 && git add -p && git commit ...

# --hard:这堆改动彻底不要了
git reset --hard HEAD~1

hard 的安全网

--hard 丢弃的提交和改动看似没了,但提交对象仍在:git reflog 找到哈希,先 git branch recovery <哈希> 保存恢复引用,再选择恢复方式,避免立即覆盖现有工作区(前提是提交对象仍存在)。未提交过的工作区改动则真的找不回——hard 前想清楚。

常见问题(FAQ)

Q:git reset 不带参数干什么?

git reset(等价 mixed HEAD):把暂存区重置到 HEAD——就是"取消所有 git add",工作区改动保留。

Q:reset 到某个历史提交而不是 HEAD~N?

git reset --hard a1b2c3d 直接回到任意提交。配合 git log --oneline 先找目标。

Q:reset 和 revert 怎么选?

本地未推送的历史用 reset 改写;已推送、共享的历史用 revert(新增反向提交)——reset 改写公开历史会坑队友。

参考资料

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台