【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 来修正,不能改写

相关推荐
无限进步_2 小时前
【C++&string】寻找字符串中第一个唯一字符:两种经典解法详解
开发语言·c++·git·算法·github·哈希算法·visual studio
木下~learning2 小时前
零基础Git入门:Linux+Gitee实战指南
linux·git·gitee·github·虚拟机·版本控制·ubunt
安科瑞小许3 小时前
35kV变电站的“智慧大脑”——综合自动化系统
大数据·网络·变电站·零碳园区
zh_xuan3 小时前
修改远程仓库名以及和本地工程同步
git
相九辞3 小时前
系统运维第1期:什么是系统运维?
大数据
tian_jiangnan3 小时前
Flink checkopint使用教程
大数据·flink
武子康3 小时前
大数据-262 实时数仓 - Canal 同步数据实战指南 实时统计
大数据·hadoop·后端
Elastic 中国社区官方博客3 小时前
将 Logstash 管道从 Azure Event Hubs 迁移到 Kafka 输入插件
大数据·数据库·elasticsearch·microsoft·搜索引擎·kafka·azure
北京软秦科技有限公司3 小时前
IA-Lab AI 检测报告生成助手:双碳目标驱动下的检测机构效率引擎,重塑报告生成与合规审核新模式
大数据·人工智能