【Git基础】03——Git 撤销与回退:改错了怎么办

​ 写代码总会手滑。改了半天发现方向错了,或者 commit 信息写错了,甚至把不该提交的东西提交上去了,这些都是日常。Git 的撤销体系看起来命令很多,但核心其实只有一句话:先判断改动在哪一层,再选择对应的撤销工具。只要这点清楚,Git 的"后悔药"其实非常好用。

引言

​ 先建立一张地图,Git 追踪改动分三层:

  • 工作区(Working Directory):你正在编辑的文件

  • 暂存区(Staging Area) :执行 git add 之后

  • 提交历史(Commit History) :执行 git commit 之后

撤销操作的方向,本质就是沿着这条链 向后退。

​ 三层结构图:工作区、暂存区、提交历史依次排列,撤销操作是沿着这条链往回走的过程。

一、场景一:还没 add,直接丢弃工作区改动

​ 你改了一个文件,还没 add,现在想把它恢复到上次提交的状态:

bash 复制代码
git restore README.md

​ 这条命令会丢弃工作区的改动 ,文件直接回到最近一次 commit 的版本。注意,这个操作是不可逆的,因为工作区的修改没有进入Git历史。

​ 旧版 Git 用的是 git checkout -- README.md,效果一样,只是语义不够清晰。现在推荐统一用 git restore。

二、场景二:已经add,但还没 commit

​ git add 之后反悔了,想把文件从暂存区拿回来:

bash 复制代码
git restore --staged README.md

​ 加了 --staged 就是针对暂存区操作。执行后,文件回到"已修改但未暂存"的状态,工作区的改动还在,只是不再准备提交了。

​ 如果想一步到位,既撤销暂存,又丢弃工作区修改,推荐分两步:

bash 复制代码
git restore --staged README.md
git restore README.md

​ 意图清晰比命令短更重要。

三、场景三:已 commit,怎么办

这里是 Git 新手最容易混乱的地方

​ 这里要区分两种情况:这个 commit 有没有推送到远程。

3.1 没推送:可以用 git reset

​ git reset 会移动HEAD指针,改写提交历史。

​ 有三种模式:

模式 改动去向
--soft 回到暂存区
默认(mixed) 回到工作区
--hard 直接丢弃
(1) commit -> 暂存区
bash 复制代码
git reset --soft HEAD~1
(2) commit -> 工作区
bash 复制代码
git reset HEAD~1
(3) commit 直接删除
bash 复制代码
git reset --hard HEAD~1

​ 三个模式的区别在于改动去哪里:--soft 退回暂存区,默认(--mixed)退回工作区,--hard 直接扔掉。--hard 用之前要想清楚,它是真正的删除按钮,改动没有备份,找回来非常麻烦。

3.2 已推送:必须用 git revert

​ 一旦 commit 推送到了远程,绝对不要用 git reset。原因很简单:远程已经有这个commit的记录,你本地改写历史之后,推送会被拒绝;就算强推成功,协作的同事拉代码时会遭遇历史冲突,现场一片混乱。

​ 正确做法是 git revert:

bash 复制代码
git revert HEAD

​ 它不会删除commit,而是会生成一个新的 commit,内容是把目标 commit 的改动反向应用一遍。历史链条不动,安全,可追溯。

复制代码
提交历史:A → B → C(需要撤销 C)
revert 后:A → B → C → C'(C' 是 C 的逆操作)

​ reset 直接把 HEAD 往回挪,C 从历史中"消失",本地没问题,但如果这个 commit 已经推送到远程,别人的历史里还有 C,强推会导致冲突。而revert 则是在 C 后面追加一个反向 commit C',历史只增不删,对协作者完全透明,这就是为什么已推送的 commit 必须用 revert。

​ 代价是历史会多一条记录,但这正是团队协作里应有的透明度。

四、git stash:保存现场,去干别的

​ 有一种场景 reset 和 revert 都处理不了:你改到一半,突然需要切分支处理紧急 bug。改动还没到能提交的程度,但直接切分支又可能出现冲突或者把改动带过去。

​ 这时候可以用 git stash:

bash 复制代码
git stash

​ 它会把当前工作区和暂存区的改动打包藏起来,让你的工作目录回到干净状态。处理完紧急任务,切回原来的分支,再把现场恢复出来:

bash 复制代码
git stash pop

​ pop 会把最近一次 stash 的内容恢复,并从 stash 列表里移除。如果想保留记录,用 git stash apply 代替。

​ 有时候同时有几个 stash,可以用 git stash list 查看,git stash pop stash@{1} 指定恢复哪一个。

五、决策表:碰到问题查这里

当前状态 目标 命令
工作区有改动,未 add 丢弃改动 git restore <file>
已 add,未 commit 撤销暂存 git restore --staged <file>
已 commit,未推送 撤销 commit git reset HEAD~1
已 commit,已推送 撤销 commit git revert <commit>
改到一半要切分支 临时保存现场 git stash / git stash pop

​ 撤销体系的核心逻辑就是一句话:改动走到哪一层,用对应层的工具往回退;已经共享出去的历史,只能用新 commit 来修正,不能改写。

相关推荐
Elasticsearch7 分钟前
一条 ES|QL 查询,涵盖365天的审计日志:在热数据和可搜索快照上执行相同的搜索
elasticsearch
howdoyoudo2026064 小时前
AI审计手记 #28:从“暂停训练”到“切断联网”——AI安全控制手段的极限升级
大数据·人工智能·安全·ai·语言模型
Elasticsearch8 小时前
Kibana:创建包含时间序列图表的仪表板
elasticsearch
曦夜日长9 小时前
Git系统篇,Git本地使用(一):从“究极进化版“到三个区域的底层原理
大数据·linux·git·elasticsearch
阿明副业观察9 小时前
2026年免费AI视频生成工具功能深度解析:有无水印、中文语音及商业用途考量
大数据·人工智能·ai作画·aigc·音视频·ai写作
2601_9627809111 小时前
2027校招准备:统计学专业如何用数据能力应聘企业经营管理管培生
大数据
宵时待雨11 小时前
GIT版本管理2:远程操作与多人协作
git
阿明副业观察11 小时前
AI视频生成技术全解:生成方法、操作流程与选型指南
大数据·人工智能·ai作画·aigc·ai写作
鬼手点金12 小时前
opencode-rules 插件
java·开发语言·前端·人工智能·chrome·git·github