撤销与清理
这一类命令有些只移动暂存区,有些会删除本地改动。执行前先确认自己要撤销的是“暂存状态”还是“文件内容本身”。
git restore <file>
git restore -- README.md用途:把指定工作区路径恢复为暂存区(index)里的内容。只有 index 与 HEAD 相同时,结果才等同于恢复到 HEAD。
若明确要忽略 index 并从当前提交恢复:
git restore --source=HEAD -- README.md旧写法:
git checkout -- README.md会丢失本地内容
如果这个文件里有未保存到提交或 stash 的修改,执行后这些修改会被覆盖。
建议先看:
git diff -- README.mdgit restore --staged --worktree <file>
git restore --staged --worktree -- README.md用途:同时撤销指定文件的暂存内容和工作区内容,让文件回到当前 HEAD 版本。
旧写法:
git checkout HEAD -- README.md适用场景:
- 某个文件已经暂存,但后来确认完全不需要这些修改。
注意:这比只运行 git reset -- README.md 更强,因为它会改工作区文件内容。
git revert:保留历史地撤销提交
git revert --no-edit HEAD用途:根据目标提交生成一个反向变化,并创建新提交。它不删除原提交,适合已共享历史中的普通提交。
使用前:
- 先用
git show HEAD确认目标;练习时只撤销专门创建的普通测试提交。 - 工作区应干净;若反向变化冲突,需要人工解决后继续,或用
git revert --abort中止。 - merge commit 需要额外选择主线父提交,初学者不要随意对 merge commit 运行 revert。
--no-edit沿用自动生成的消息,避免练习时被未知编辑器阻塞;真实项目仍应按团队要求审查消息。
git reset --hard
git reset --hard用途:把当前分支、暂存区和工作区一起重置到 HEAD,丢弃所有已跟踪文件的本地修改。
高风险操作
这个命令会删除已跟踪文件的未提交修改;为写回目标提交,它还可能删除阻碍已跟踪路径写入的未跟踪文件或目录。reflog 不能找回从未提交的工作区内容。只在可丢弃的隔离仓库中使用,并先运行
git status --short、git diff与git diff --staged。
常见安全替代:
git stash
git status --short如果只是想取消暂存,不要用 --hard,用:
git resetgit clean
git clean用途:删除未被 Git 跟踪的文件。实际使用中通常需要加 -f,因为 Git 默认会保护性拒绝直接删除。
建议流程:
git clean -n -d
git clean -fd说明:
-n是 dry run,只显示将删除什么,不真正删除。-f表示确认执行。-d表示包含未跟踪目录。- 默认不删除被 ignore 的路径;
-x才会把 ignored 路径纳入,初学主线不练这个选项。 - 嵌套 Git 仓库还有额外保护,不要通过叠加
-f去绕过不理解的边界。
不会进入提交历史
未跟踪文件没有被 Git 保存。删除后通常不能通过 Git 恢复。
git stash
git stash用途:临时保存当前已跟踪文件的暂存与未暂存修改,并清理这些修改。若仍有未跟踪或 ignored 路径,工作区不一定完全干净。
适用场景:
- 需要临时切换分支,但当前工作还不适合提交。
- 想先把本地修改挪开,拉取远程更新或复现问题。
常用补充命令:
git stash list
git stash pop
git stash apply说明:
pop会应用最近一次 stash,并在成功后删除该 stash。apply只应用,不删除 stash 记录。- 默认
git stash不包含未跟踪或 ignored 文件;-u包含未跟踪文件,-a才连 ignored 文件一起包含。执行前先检查清单,避免把凭据带进 stash。
选择撤销命令的判断表
| 目标 | 影响历史 | 是否适合共享历史 | 推荐命令 |
|---|---|---|---|
| 只取消暂存,保留文件内容 | 不变 | 是 | git restore --staged -- README.md |
| 用 index 内容覆盖工作区文件 | 不变 | 是,但会丢本地内容 | git restore -- README.md |
用 HEAD 同时覆盖 index 与工作区 | 不变 | 是,但会丢本地内容 | git restore --source=HEAD --staged --worktree -- README.md |
| 反向撤销一个已共享普通提交 | 新增反向提交 | 通常是 | git revert --no-edit HEAD |
| 移动本地分支并保留文件修改 | 改写当前分支入口 | 尚未共享时才考虑 | git reset --mixed HEAD~1 |
| 丢弃全部已跟踪本地修改 | 分支目标可变,文件会丢 | 否,仅隔离仓库 | git reset --hard HEAD |
| 删除未跟踪文件 | 不进入历史且通常不可恢复 | 与历史无关,但高风险 | 先 git clean -n -d,隔离仓库才考虑 git clean -fd |
| 临时挪开已跟踪修改 | 历史不变,新增 stash 引用 | 本地操作 | git stash push -m "wip: explain purpose" |
最小练习
在 版本控制实战与自测 的隔离仓库中,分别验证“恢复工作区”“取消暂存”和“revert 专用普通提交”。每一步都记录前后的 status、diff、diff --staged 和 log,并写明内容、index、历史与分支指针各自是否变化。
参考资料
按 Git 2.55.0 官方文档核验,获取日期:2026-07-14。