Git 如何把文件恢复到指定的历史版本

用 git restore --source 指定历史提交恢复单文件;加 --staged --worktree 可同时更新暂存区与工作区。说明与 checkout、revert 的区别及如何撤销恢复。

最佳实践
版本分支与历史整合插画

一句话回答:git checkout <提交号> -- <文件路径> 把该文件还原到指定提交的内容(Git 2.23+ 等价新写法:git restore --source=<提交号> --staged --worktree -- <文件>)。还原结果同时写入工作区和暂存区,其他文件不受影响,确认后正常 commit 即可形成一次"回滚该文件"的新提交。

执行前先备份该文件的未提交改动:下面命令会覆盖它们。只希望先改工作区以便检查时,用 git restore --source=<提交号> -- <文件>,不加 --staged;它与同时更新两个区域的 checkout 用法不完全相同。

基本用法

# 还原到指定提交
git checkout abc1234 -- src/config.js

# 还原到"某个提交之前"的版本(^ 表示其父提交)
git checkout abc1234^ -- src/config.js

# 还原到某个标签时的状态
git checkout v1.2.0 -- src/config.js

# 查看差异再决定
git diff HEAD abc1234 -- src/config.js

执行后 git status 会显示该文件处于已修改状态,git diff --cached 能看到与当前版本的具体差异。

新写法(Git 2.23+)

git restore --source=abc1234 --staged --worktree src/config.js

restore 语义更明确(--source 指定来源版本),与 checkout 的还原文件用法等价。

与 revert 的区别

方式 效果 历史
checkout 提交 -- 文件 文件内容直接换成旧版 不产生新提交,等你手动 commit
git revert 提交 生成"反向补丁"提交 自动产生新提交(针对整个提交而非单文件)

回滚单个文件用 checkout/restore 最干净;要撤销整个提交的所有改动才用 revert。

配套技巧

git log --oneline -- src/config.js     # 先查这个文件的变更历史,找到目标提交
git show abc1234:src/config.js         # 不改文件,直接看那个版本的内容

常见问题(FAQ)

Q:还原后想撤销这次还原?

A:还没 commit 时 git restore --staged --worktree src/config.js(或 git checkout HEAD -- 文件)即可还原回当前版本;已 commit 后 HEAD 已包含恢复结果,不能靠再 checkout HEAD 撤销它;若该提交只做了本次恢复,可 git revert <该恢复提交>,否则从恢复前的明确提交再取回此文件并审核提交。

Q:文件名在历史中改过,能还原旧名字的内容吗?

A:可以。checkout 时用那个提交时刻的路径(旧名),会在工作区恢复该旧路径,不会自动映射到现在的新名字;要保留新名字,应先查看 git show <提交>:<旧路径>,备份后再将所需内容应用到新路径。配合 git log --follow -- 文件 追踪改名历史。

Q:批量还原整个目录到某版本?

A:git checkout abc1234 -- src/ 支持目录路径。大范围回滚也可以考虑 git revert 若干提交,语义更清晰。

核查依据

本文依据官方文档核对,示例未在实际业务环境运行;上线前请按部署版本、权限与数据范围验证。


延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台