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

Posted

技术标签:

【中文标题】恢复到不属于任何分支的提交【英文标题】:revert to a commit that does not belong to any branch 【发布时间】:2021-09-22 10:52:15 【问题描述】:

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

我试过了:

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

甚至

git reset <commit> --hard

但它不起作用:

fatal: bad revision

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

【问题讨论】:

你看到这个提交了吗?也许git reflog 可以帮助恢复更改。 @CoolMind 怎么样? 这个命令我不知道怎么用(试了一天,没有成功)。它显示了操作历史记录,并且可以还原更改。 您可以使用 reflog 撤消几乎所有 Git 错误,正如 @CoolMind 建议的那样,即使在推送之后也是如此。这可能会有所帮助:til.hashrocket.com/posts/9c3ea5a6f6-undo-any-git-action- 一个不错的样本!不要在家里重复它(笑话)。在 Git 中创建另一个项目,执行一些操作并尝试重现 @JakeWorth 代码,然后在工作项目中重复相同的操作。 【参考方案1】:

这个命令:

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 实现偷偷地共享多个存储fork,因此有时可以直接访问不在 您的 fork 中的提交。2 在这种情况下,克隆您自己的 fork 可能无法让您访问对象(再次参见脚注 2)。不过,Git 的一项新功能3 意味着您可以通过其哈希 ID 访问任何对象,因此您可以直接通过其哈希 ID git fetch 对象。


1Git 混合了 POSIX 和 GNU 选项思想,但也有自己的曲折。类 Unix 系统上的许多命令行命令遵循更严格的纯 POSIX 模型,其中以破折号为前缀的选项——无论是像 -x 这样的短选项还是像 --extended 这样的长选项——必须之前出现附加的可选参数,例如文件名。一般来说,写这样的东西是一个好习惯,这样当你使用 sed 命令时,你就不会被选项顺序绊倒。

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

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

【讨论】:

以上是关于恢复到不属于任何分支的提交的主要内容,如果未能解决你的问题,请参考以下文章

重新提交在 git 中恢复的提交

通过子分支的不同提交在主分支上添加恢复的更改不会反映在主分支上

如何恢复从一个分支合并的所有提交

将推送的分支恢复为具体的提交

git - 如何判断提交属于哪个分支?

从分支 B 合并时,在分支 A 上恢复的提交不存在