Appearance
重置提交
概述
git reset 是 Git 中最强大但也最危险的命令之一。它可以移动分支指针,改变提交历史。理解 git reset 的三种模式对于安全地操作 Git 至关重要。
git reset 三种模式
模式概览
--soft --mixed (默认) --hard
│ │ │
HEAD 指针 │ 移动 │ 移动 │ 移动
暂存区 │ 不变 │ 重置 │ 重置
工作区 │ 不变 │ 不变 │ 重置三种模式对比
| 模式 | HEAD | 暂存区 | 工作区 | 用途 |
|---|---|---|---|---|
| --soft | 移动 | 不变 | 不变 | 撤销提交,保留修改 |
| --mixed | 移动 | 重置 | 不变 | 撤销提交和暂存 |
| --hard | 移动 | 重置 | 重置 | 完全撤销,丢弃所有 |
--soft 模式
工作原理
# 重置前
HEAD -> C (暂存区和工作区都有 C 的内容)
|
B
|
A
# git reset --soft HEAD~1 后
HEAD -> B (暂存区和工作区仍保留 C 的修改)
|
A
# 提交 C 被撤销,但修改保留在暂存区使用场景
bash
# 场景 1:撤销最近的提交,重新提交
git commit -m "WIP: feature"
# 发现提交信息不对,或想修改内容
git reset --soft HEAD~1
# 修改后重新提交
git commit -m "Add feature X"
# 场景 2:合并多个提交
git reset --soft HEAD~3
git commit -m "Combined commit"
# 场景 3:拆分提交
git reset --soft HEAD~1
# 重新选择要提交的内容
git add file1.txt
git commit -m "First part"
git add file2.txt
git commit -m "Second part"操作示例
bash
# 查看当前状态
git log --oneline -3
# c3d4e5f (HEAD -> main) Third commit
# b2c3d4e Second commit
# a1b2c3d First commit
# 软重置到上一个提交
git reset --soft HEAD~1
# 查看状态
git status
# Changes to be committed:
# modified: file.txt
# 暂存区保留了第三次提交的修改
# 可以重新编辑或直接提交--mixed 模式
工作原理
# 重置前
HEAD -> C (暂存区和工作区都有 C 的内容)
|
B
|
A
# git reset --mixed HEAD~1 后
HEAD -> B (暂存区被重置,工作区保留 C 的修改)
|
A
# 提交 C 被撤销,修改保留在工作区(未暂存)使用场景
bash
# 场景 1:撤销提交和暂存
git commit -m "Wrong commit"
git reset HEAD~1
# 等同于 git reset --mixed HEAD~1
# 场景 2:重新组织提交
git reset HEAD~2
# 修改在工作区,可以重新选择暂存内容
# 场景 3:撤销 git add
git reset file.txt
# 等同于 git restore --staged file.txt操作示例
bash
# 查看当前状态
git log --oneline -3
# c3d4e5f (HEAD -> main) Third commit
# b2c3d4e Second commit
# a1b2c3d First commit
# 混合重置(默认模式)
git reset HEAD~1
# 或明确指定
git reset --mixed HEAD~1
# 查看状态
git status
# Changes not staged for commit:
# modified: file.txt
# 修改在工作区,但未暂存--hard 模式
工作原理
# 重置前
HEAD -> C (暂存区和工作区都有 C 的内容)
|
B
|
A
# git reset --hard HEAD~1 后
HEAD -> B (暂存区和工作区都被重置)
|
A
# 提交 C 被撤销,所有修改丢失使用场景
bash
# 场景 1:完全放弃最近的修改
git reset --hard HEAD~1
# 场景 2:恢复到干净状态
git reset --hard HEAD
# 场景 3:同步远程分支
git fetch origin
git reset --hard origin/main
# 场景 4:撤销错误的合并
git reset --hard ORIG_HEAD操作示例
bash
# 警告:此操作不可逆!
git log --oneline -3
# c3d4e5f (HEAD -> main) Third commit
# b2c3d4e Second commit
# a1b2c3d First commit
# 硬重置
git reset --hard HEAD~1
# 查看状态
git status
# nothing to commit, working tree clean
# 所有修改已丢失
git log --oneline -3
# b2c3d4e (HEAD -> main) Second commit
# a1b2c3d First commit回退到指定提交
使用提交哈希
bash
# 查看提交历史
git log --oneline
# e5f6g7h (HEAD -> main) Fifth commit
# d4e5f6g Fourth commit
# c3d4e5f Third commit
# b2c3d4e Second commit
# a1b2c3d First commit
# 回退到指定提交
git reset --hard b2c3d4e
# 当前状态
git log --oneline
# b2c3d4e (HEAD -> main) Second commit
# a1b2c3d First commit使用相对引用
bash
# 回退 1 个提交
git reset HEAD~1
# 回退 3 个提交
git reset HEAD~3
# 回退到上一个提交
git reset HEAD^
# 回退到上上个提交
git reset HEAD^^
# 回退 5 个提交
git reset HEAD~5使用分支名
bash
# 重置到远程分支
git reset --hard origin/main
# 重置到其他分支
git reset --hard feature
# 重置到标签
git reset --hard v1.0.0恢复误操作
使用 ORIG_HEAD
bash
# Git 会在危险操作前保存 ORIG_HEAD
git reset --hard HEAD~1
# 恢复到操作前
git reset --hard ORIG_HEAD使用 reflog
bash
# 查看操作历史
git reflog
# e5f6g7h (HEAD -> main) HEAD@{0}: reset: moving to HEAD~1
# f6g7h8i HEAD@{1}: commit: Fifth commit
# ...
# 恢复到指定操作
git reset --hard HEAD@{1}
# 或使用提交哈希
git reset --hard f6g7h8i恢复流程
bash
# 1. 查看操作历史
git reflog
# 2. 找到误操作前的提交
# 例如:a1b2c3d HEAD@{5}: commit: Important work
# 3. 恢复
git reset --hard a1b2c3d
# 或使用 reflog 引用
git reset --hard HEAD@{5}reset 常用技巧
撤销最近 N 个提交
bash
# 撤销最近 3 个提交,保留修改在暂存区
git reset --soft HEAD~3
# 撤销最近 3 个提交,保留修改在工作区
git reset HEAD~3
# 完全撤销最近 3 个提交
git reset --hard HEAD~3修改最后一次提交
bash
# 方法 1:使用 --amend
git commit --amend
# 方法 2:使用 reset
git reset --soft HEAD~1
# 修改后重新提交
git commit -m "New message"撤销合并
bash
# 撤销最近的合并
git reset --hard ORIG_HEAD
# 或指定合并前的提交
git reset --hard HEAD~1同步远程分支
bash
# 本地分支落后于远程
git fetch origin
git reset --hard origin/main
# 注意:这会丢失本地未推送的提交reset vs revert
bash
# reset:重置历史
git reset --hard HEAD~1
# 删除提交,改变历史
# revert:创建新提交来撤销
git revert HEAD
# 创建新提交,不改变历史
# 选择建议:
# - 本地未推送的提交:使用 reset
# - 已推送的公共提交:使用 revert安全检查清单
bash
# 在执行 reset --hard 前,检查:
# 1. 是否有未提交的重要修改?
git status
# 2. 是否有未推送的重要提交?
git log origin/main..HEAD
# 3. 是否需要备份?
git branch backup-branch
# 4. 确认操作
git reset --hard HEAD~1总结
--soft:撤销提交,保留暂存区和工作区--mixed:撤销提交和暂存,保留工作区(默认)--hard:完全撤销,丢弃所有修改- 使用 reflog 可以恢复误操作
- 公共分支避免使用 reset,使用 revert
下一步
学习完重置提交后,建议继续学习:
