Git Reset命令介绍(用于移动HEAD,并选择是否同步更新暂存区工作区)三种模式:--soft、--mixed(默认)、--hard;修改最近提交、合并多个提交、取消git add、回退版本回退
注意区分:git reset和git reset HEAD~1(功能完全不同,git reset只用于取消文件暂存)
| 命令 | 移动HEAD | 重置暂存区 | 保留工作目录更改 | 主要用途 |
|---|---|---|---|---|
git reset | ❌ 不移动 | ✅ 重置到HEAD | ✅ 保留 | 取消文件暂存 |
git reset HEAD~1 | ✅ 移动到前一个提交 | ✅ 重置 | ✅ 保留 | 撤销最后一次提交,保留修改 |
git reset --mixed HEAD~1 | ✅ 移动到前一个提交 | ✅ 重置 | ✅ 保留 | 同上,与上者等价 |
文章目录
- Git Reset 命令详解:撤销提交、回退代码与重置状态
- 一、理解 Git 三大区域(核心前提)
- 1. Working Directory(工作区)
- 2. Staging Area(暂存区 / Index)
- 3. Repository(本地仓库)
- 二、git reset 的本质
- 三、reset 的三种模式(最核心)
- 四、git reset --soft
- 作用
- 示例
- 等价理解
- 常见用途
- 1. 修改最近一次 commit
- 2. 合并多个 commit
- 五、git reset --mixed(默认)
- 作用
- 示例
- 状态变化
- 最常见用途
- 1. 取消 git add
- 2. 拆分一次提交
- 六、git reset --hard
- 作用
- 示例
- 七、hard reset 的危险性
- 非常重要
- 使用前建议
- 八、reset 常见写法
- 1. 回退一个 commit
- 2. 回退两个 commit
- 3. 回退到指定 commit
- 4. 仅取消暂存
- 5. 重置所有暂存
- 九、HEAD~1 是什么意思?
- 含义
- 十、git reset 的典型场景
- 场景 1:commit message 写错
- 场景 2:提交了不该提交的文件(将指定文件从暂存区Staging Area中移除,但保留工作目录中的修改内容)
- 场景 3:commit 太大,想拆分
- 场景 4:彻底放弃本地修改
- 场景 5:本地回退到远程版本
- 十一、git reset 与 git revert 的区别
- git reset
- git revert
- 对比
- 十二、已经 push 后还能 reset 吗?
- force强制推送
- 注意:如果已经push了,再用reset,直接用push不加参数是百分之百拒绝的
- 更安全方式
- 十三、reset 后如何恢复?(reflog)
- 示例
- 十四、reset 的思维模型(非常重要)
- 十五、实际开发建议
- 推荐原则
- 日常取消 add
- 修改 commit
- 已 push 的 commit
- 慎用 hard
- 十六、总结
Git Reset 命令详解:撤销提交、回退代码与重置状态
在 Git 的日常使用中,git reset是一个非常强大、也非常容易误用的命令。
很多开发者第一次接触它时,都会被它的行为搞混:
- 为什么有时候只是取消暂存?
- 为什么有时候会回退 commit?
- 为什么有时候代码直接没了?
--soft、--mixed、--hard到底有什么区别?
这篇文章会系统讲清楚:
git reset的本质- 三种 reset 模式
- reset 对 Git 三大区域的影响
- 常见使用场景
- 与
git revert的区别 - 如何避免误操作
一、理解 Git 三大区域(核心前提)
学习git reset前,必须先理解 Git 的三个区域。
1. Working Directory(工作区)
你实际编辑代码的目录。
例如:
vimapp.py修改的内容先存在工作区。
2. Staging Area(暂存区 / Index)
通过:
gitadd加入的内容。
它表示:
“下一次 commit 我要提交这些内容”
3. Repository(本地仓库)
通过:
gitcommit真正保存的历史记录。
二、git reset 的本质
一句话理解:
git reset用于“移动 HEAD”,并选择是否同步更新暂存区和工作区。
也就是说:
gitreset本质上是在:
HEAD -> 指向新的 commit然后根据参数决定:
- 是否修改暂存区
- 是否修改工作区
三、reset 的三种模式(最核心)
Git reset 最重要的三个模式:
| 模式 | HEAD | 暂存区 | 工作区 |
|---|---|---|---|
--soft | ✔ | ❌ | ❌ |
--mixed(默认) | ✔ | ✔ | ❌ |
--hard | ✔ | ✔ | ✔ |
这是整个 reset 的核心。
下面逐个解释。
四、git reset --soft
作用
只移动 HEAD。
不会修改:
- 暂存区
- 工作区
示例
当前:
A -> B -> C (HEAD)执行:
gitreset--softHEAD~1结果:
A -> B (HEAD)commit C 被“取消”。
但是:
- C 的代码还在
- 并且仍然在暂存区
等价理解
相当于:
“撤销 commit,但保留提交内容”
常见用途
1. 修改最近一次 commit
例如:
(提交信息不小心写错了)
gitcommit-m"wrong message"想改 commit message:
gitreset--softHEAD~1gitcommit-m"correct message"# 因为没有影响暂存区和工作去,可以直接改为正确提交信息再提交2. 合并多个 commit
例如:
A -> B -> C -> D想把:
C + D合并:
gitreset--softHEAD~2gitcommit-m"combined changes"五、git reset --mixed(默认)
这是默认模式。
即:
gitreset HEAD~1等价于:
gitreset--mixedHEAD~1作用
- 移动 HEAD
- 重置暂存区
- 保留工作区
示例
执行:
gitreset--mixedHEAD~1结果:
- commit 被取消
- 文件修改还在
- 但不再处于 staged 状态
状态变化
之前:
已 commit之后:
modified需要重新:
gitaddgitcommit最常见用途
1. 取消 git add
例如:
gitadd.误加文件。
取消暂存:
gitreset注:
git reset相当于git reset HEAD,只重置暂存区(index)到HEAD状态,不会移动HEAD指针。主要用于取消文件的暂存状态(unstage files),比如把已经git add的文件移出暂存区不会回退任何提交。
或者:
gitreset file.txt2. 拆分一次提交
比如:
你一次提交了很多文件:
gitcommit想拆成多个 commit:
gitreset HEAD~1然后重新:
gitaddfileAgitcommitgitaddfileBgitcommit六、git reset --hard
这是最危险的模式。
作用
同时重置:
- HEAD
- 暂存区
- 工作区
示例
执行:
gitreset--hardHEAD~1结果:
- commit 消失
- staged 消失
- 工作区修改也消失
相当于:
“彻底回到旧版本”
七、hard reset 的危险性
非常重要
gitreset--hard可能导致:
未提交代码永久丢失
尤其:
gitreset--hardorigin/main会直接覆盖本地修改。
使用前建议
先查看状态:
gitstatus或者先备份:
gitstash八、reset 常见写法
1. 回退一个 commit
gitreset HEAD~12. 回退两个 commit
gitreset HEAD~23. 回退到指定 commit
gitreset a1b2c3d4. 仅取消暂存
gitreset file.txt5. 重置所有暂存
gitreset九、HEAD~1 是什么意思?
例如:
A -> B -> C -> D (HEAD)含义
| 写法 | 含义 |
|---|---|
HEAD | 当前 commit |
HEAD~1 | 上一个 commit |
HEAD~2 | 上上个 commit |
十、git reset 的典型场景
场景 1:commit message 写错
gitreset--softHEAD~1gitcommit-m"new message"场景 2:提交了不该提交的文件(将指定文件从暂存区Staging Area中移除,但保留工作目录中的修改内容)
gitreset HEAD file.txt等价于:
gitreset file.txt场景 3:commit 太大,想拆分
gitreset HEAD~1重新 add。
场景 4:彻底放弃本地修改
gitreset--hard场景 5:本地回退到远程版本
gitfetch origingitreset--hardorigin/main十一、git reset 与 git revert 的区别
这是高频面试题。
git reset
本质:
修改历史
特点:
- commit 消失
- 会改变历史(指改变提交历史,以及“可能”改变工作区代码,如果用hard模式
git reset --hard HEAD~1的话) - 不适合已经 push 的 commit
git revert
本质:
新建一个“反向 commit”
例如:
A -> B -> Crevert C 后:
A -> B -> C -> DD 是“撤销 C”的 commit。
对比
| 对比项 | reset | revert |
|---|---|---|
| 是否改历史 | ✔ | ❌ |
| 是否安全 | 较危险 | 更安全 |
| 是否适合已 push | ❌ | ✔ |
| 是否删除 commit | ✔ | ❌ |
十二、已经 push 后还能 reset 吗?
可以。
但危险。
force强制推送
gitreset--hardHEAD~1gitpush--force会:
- 改写远程历史
- 影响团队成员
注意:如果已经push了,再用reset,直接用push不加参数是百分之百拒绝的
更安全方式
优先:
gitrevert十三、reset 后如何恢复?(reflog)
很多人不知道:
Git 很少真正删除 commit。
可以通过:
gitreflog查看历史 HEAD。
示例
gitreflog输出:
a1b2c3 HEAD@{0}: reset: moving to HEAD~1 d4e5f6 HEAD@{1}: commit: add feature| 操作 | reflog 索引 | 时间顺序 |
|---|---|---|
commit: add feature | HEAD@{1} | 前 |
reset: moving... | HEAD@{0} | 后 |
(数字越大,时间越早)
恢复:
gitreset--hardd4e5f6十四、reset 的思维模型(非常重要)
记住一句话:
reset = 移动 HEAD然后:
| 模式 | 是否同步暂存区 | 是否同步工作区 |
|---|---|---|
| soft | 否 | 否 |
| mixed | 是 | 否 |
| hard | 是 | 是 |
十五、实际开发建议
推荐原则
日常取消 add
用:
gitreset修改 commit
用:
gitreset--soft已 push 的 commit
优先:
gitrevert慎用 hard
尤其:
gitreset--hard执行前一定确认。
十六、总结
git reset是 Git 中最核心、也最容易误操作的命令之一。
它真正的本质是:
移动 HEAD,并决定是否同步暂存区和工作区。
记住这张表即可理解 90% 的 reset:
| 模式 | HEAD | 暂存区 | 工作区 |
|---|---|---|---|
| soft | ✔ | ❌ | ❌ |
| mixed | ✔ | ✔ | ❌ |
| hard | ✔ | ✔ | ✔ |
开发中最常见的用途:
- 撤销 commit
- 取消暂存
- 拆分 commit
- 回退版本
- 放弃修改
但同时:
git reset --hard也可能让代码永久丢失。
所以:
- reset 前先
git status - 重要修改先
git stash - 已 push 历史优先
git revert
这样才能安全、高效地使用 Git。
