Skip to content

撤销工作区改动

工作区的改动是最"脆弱"的,尚未被 Git 记录。本节介绍如何撤销工作区中已修改但尚未暂存的改动。

git restore(新语法,推荐)

git restore 是 Git 2.23+ 引入的命令,专门用于恢复工作区文件:

bash
# 撤销单个文件的修改(恢复到暂存区/最近提交的状态)
git restore README.md
git restore src/app.js

# 撤销多个文件
git restore README.md src/app.js

# 撤销整个目录
git restore src/

# 撤销所有工作区改动(恢复到 HEAD 状态)
git restore .

警告:此操作不可撤销!工作区的未提交修改将永久丢失。执行前请确认。

restore 的 --source 选项

默认情况下,git restore 从暂存区恢复。可以指定从其他来源恢复:

bash
# 从 HEAD(最近提交)恢复
git restore --source=HEAD README.md

# 从特定提交恢复
git restore --source=abc123 README.md

# 从特定分支恢复某文件
git restore --source=main src/config.js

git checkout -- (旧语法)

在 Git 2.23 之前,使用 checkout 来撤销工作区改动:

bash
# 旧语法(仍然有效,但不推荐用于新项目)
git checkout -- README.md
git checkout -- src/app.js

# 撤销所有工作区改动
git checkout -- .
git checkout .

-- 的作用是将文件路径与分支名/提交哈希区分开,避免歧义。

撤销所有工作区改动

bash
# 方式1:使用 restore(推荐)
git restore .

# 方式2:使用 checkout
git checkout -- .

# 方式3:clean + checkout(同时删除未跟踪文件)
git clean -fd       # 删除未跟踪的文件和目录
git restore .       # 撤销已跟踪文件的修改

git clean:清理未跟踪文件

git restore 只能恢复已跟踪文件。未跟踪的文件(新建但未 git add 的文件)需要用 git clean 删除:

bash
# 查看哪些未跟踪文件会被删除(不实际执行)
git clean -n
git clean --dry-run

# 删除未跟踪文件
git clean -f
git clean --force

# 删除未跟踪文件和目录
git clean -fd

# 删除未跟踪文件、目录,以及被 .gitignore 忽略的文件
git clean -fdx

# 交互式清理
git clean -i

警告git clean 删除的文件不可恢复!请先用 -n 预览。

选择性撤销

恢复特定版本的文件

bash
# 恢复某个文件到 HEAD 状态(最近提交)
git restore README.md

# 恢复某个文件到 3 次提交前的状态
git restore --source=HEAD~3 README.md

# 恢复某个文件到特定标签时的状态
git restore --source=v1.0.0 src/config.js

# 从另一个分支恢复文件
git restore --source=feature/new-config config/settings.json

使用 git stash 临时保存

如果你不想丢弃改动,但需要暂时切换到干净状态,使用 stash:

bash
# 保存当前改动
git stash

# 切换分支或做其他操作...

# 恢复之前保存的改动
git stash pop

实际场景

场景1:修改了错误的文件

bash
# 发现不小心修改了不该改的文件
git status
# modified: config/production.json

# 立即撤销
git restore config/production.json

场景2:本地测试修改,不想提交

bash
# 临时修改了 debug 配置
echo "debug: true" >> config.json

# 测试完后撤销
git restore config.json

场景3:大幅修改后发现思路错了

bash
# 想放弃当前所有修改,从最近提交重新开始
git status   # 先看看改了什么
git restore . && git clean -fd  # 全部清理

场景4:恢复误删的文件

bash
# 不小心删除了一个已提交的文件
rm src/important.js

# 从最近提交恢复
git restore src/important.js

对比新旧语法

操作新语法(推荐)旧语法
撤销文件修改git restore <file>git checkout -- <file>
撤销所有修改git restore .git checkout -- .
从指定版本恢复git restore --source=<ref> <file>git checkout <ref> -- <file>

为什么推荐新语法?

  • git restore 语义更明确(只用于恢复文件)
  • git checkout 承担太多职责(切换分支、恢复文件、检出提交),容易混淆

总结

场景命令
撤销单个文件修改git restore <file>
撤销所有工作区修改git restore .
从指定提交恢复文件git restore --source=<ref> <file>
删除未跟踪文件(先预览)git clean -n 然后 git clean -fd

操作前务必确认:工作区的改动一旦丢弃便不可恢复。如果不确定,先用 git stash 保存再操作。