恢复到不属于任何分支的提交

问题描述

我不小心强行推送了我的 repo,所以我丢失了一些不属于任何分支的提交

enter image description here

我试过了:

git revert --no-commit <commit>..HEAD

甚至

git reset <commit> --hard

但它不起作用:

fatal: bad revision

有没有办法恢复这个提交?

解决方法

这个命令:

git reset <commit>--hard

是最接近纠正的,但它至少包含一个错误:--hard 与提交哈希物理连接,因此哈希看起来像 a1234567--hard,这不是有效的哈希 ID。

你可能真的跑了:

git reset --hard <commit>

或:

git reset <commit> --hard

(将选项 --hard 放在非选项参数的“错误的一边”,但 Git 容忍这种情况1)。如果这仍然不起作用,并且 Git 仍然 抱怨它无法将哈希 ID 识别为有效提交 (fatal: bad revision),则表明 您的 Git 存储库缺少此提交。这并不奇怪,因为您包含的图片说:

⚠️ 这次提交不属于这个仓库的任何分支,可能属于仓库外的一个分支。

此特定消息是那些提供“分叉”(包括 GitHub 和 Bitbucket)的托管系统所特有的:这些 Web 托管站点上轻微(或严重)被黑客入侵的 Git 实现偷偷地共享多个存储分叉,以便有时可以直接访问不在分叉中的提交。2在这种情况下,克隆自己的分叉可能无法访问该提交对象(再次参见脚注 2)。不过,Git 的一项新功能是,3 意味着您可以通过其哈希 ID 访问任何对象,因此您可以通过其哈希 ID 直接 git fetch 对象。


1Git 遵循 POSIX 和 GNU 选项思想的混合,有自己的曲折。类 Unix 系统上的许多命令行命令都遵循更严格的 POSIX-only 模型,其中以破折号为前缀的选项 - 无论是像 -x 这样的短选项还是像 --extended 这样的长选项 - 必须before 任何其他可选参数,例如文件名。写这样的东西通常是一个好习惯,这样当您使用 sed 命令时,您就不会被选项顺序绊倒。

2这有明显的安全隐患,如果网络托管站点正确地保证安全,他们不会让你访问你没有的任何提交至少暂时可以访问,足够长的时间让您复制提交。如果这种访问被“撤销”,他们可能不应该让您访问提交,但是正确支持撤销已经足够困难了,他们很可能不会打扰,借口您访问它,并且您可能在那段时间复制了 ,所以现在没有必要关闭谷仓门,因为这匹马(可能)是克隆的。显然,低成本复制经济与稀缺经济有着根本的不同,在稀缺经济中,如果拥有物品 X,其他人就无法拥有它,以及这里的规则仍在发展中。

3这是新的部分克隆功能。