误删文件后,90%的情况可用git checkout head -- file恢复未暂存的删除;已暂存删除需用git restore --source=head --staged --worktree file;悬空对象则依赖git fsck --lost-found捞取候选提交。

误删文件后,90% 的情况只需一条命令就能找回——前提是还没 git add 或 git commit 那个“删除”操作。方法不对,反而会把线索覆盖掉;方法对了,3 秒内还原。
git checkout HEAD -- file:恢复刚删、没暂存的文件
这是最常见也最容易敲错的命令。执行 git status 后看到 deleted: src/api/client.ts,就属于这一类。
- 必须带双横线
--,否则 Git 会当成切换分支,报错error: pathspec 'src/api/client.ts' did not match any file(s) known to git -
HEAD可换成具体分支名,比如你想从main恢复,就写git checkout main -- package.json - Windows 下路径含空格时,
file必须加引号:git checkout HEAD -- "tests/unit test.spec.ts" - 它会直接覆盖当前工作区同名文件(如果存在),且不检查是否已有未提交修改——删之前你改过这文件?那改的内容就丢了
git restore --source=HEAD --staged --worktree file:已 git add 过删除动作的唯一解
你执行了 git add deleted-config.json,然后又 rm deleted-config.json,此时 git status 显示 deleted: deleted-config.json 并标为 staged。这时候 git checkout HEAD -- 虽然还能用,但语义不清、容易漏操作。
- 漏掉
--worktree:文件依然消失,只取消了暂存 - 漏掉
--staged:暂存区还留着“删除记录”,下次git commit会真删掉它 - 别依赖缩写
-s HEAD -S -W,参数顺序和含义易混淆,建议写全 - 仅适用于 Git 2.23+;老版本请退回用
git reset HEAD <code>file&& git checkout HEAD --file
git fsck --lost-found:文件已从分支指针上“消失”,只剩悬空对象
你执行过 git reset --hard HEAD~1 或 git rebase -i 后,原提交不再被任何分支引用,但对象可能还在 Git 对象库里——这是最后的抢救机会,不是恢复单个文件,而是先捞出候选提交。
- 运行
git fsck --lost-found,输出里类似lost-commit abc123的行是候选提交哈希 - 对每个哈希检查是否含你要的文件:
git ls-tree -r abc123 | grep your-file-name - 确认后执行:
git checkout abc123 -- path/to/your-file -
git fsck不保证一定能找到——如果对象已被git gc清理(Git 可能在后台自动触发),这条路就断了
别碰 git reset --hard 和 git gc,除非你清楚后果
很多恢复失败,不是因为方法不对,而是后续操作把线索覆盖了。看到 deleted: 就立刻 git add .?那是往火坑里跳——它会把“删除”动作暂存,让 git checkout -- 失效,逼你走更绕的 git restore 路径,甚至直接进 fsck 模式。
真正关键的不是记住所有命令,而是第一时间判断:那个文件最后一次被提交是在哪次 commit?有没有人动过 reflog?有没有执行过 hard reset?这些信息比命令本身更决定成败。











