12 October 2025 - 字数统计：1736 - 阅读大约需要6分钟 - Hits: Loading...

# 一次找回GitHub上被删除仓库的经历

by mayx

这是一篇创建于 天前的文章，其中的信息可能已经有所发展或是发生改变。

AI摘要

这篇文章讲述了作者通过GitHub的Fork特性找回一个被删除的Brainfuck可视化演示仓库的经历。由于原仓库和作者主页都已消失，作者推测GitHub在Fork时会共享对象库，只要有任意一个Fork仓库存在，GitHub就会保留所有对象，从而可以通过找到一个Fork仓库的最新提交Hash值来还原目标仓库。作者通过Linux内核仓库的Fork进行验证，随后在互联网档案馆上找到目标仓库的Fork以及其Hash值，最终通过Git命令将本地仓库的HEAD指针指向目标提交，成功恢复了该仓库的代码，并将其部署到自己的GitHub Pages上。最后，作者发现Software Heritage组织会保存所有代码，因此在遇到类似情况时可以直接通过该平台进行查找。

- 起因
- GitHub的特性
- 找回仓库
- 结局

在GitHub中寻找踪迹也许是非常简单的事情……

#
起因

前段时间，有人和我聊天的时候提到了Brainfuck语言，让我回想起了高中时写的演讲稿。那时候我在演讲时也介绍了Brainfuck语言。对于Brainfuck的解释器，各种语言都可以实现，不过我当时为了方便理解用了一个在GitHub Pages上的网站，用可视化的方式演示了它的运行过程，效果很不错。现在既然聊到了，自然就想分享一下这个演示的网站，但我正想打开时，发现网站已经404了😰。

在GitHub Pages上的网站都有对应的仓库，现在不仅原仓库消失了，连作者的首页都打不开，看样子是完全退出GitHub了……那么我想找到这个网站的想法就无法实现了吗？不过GitHub有些有意思的特性也许能帮助我找回这个网站。

#
GitHub的特性

在GitHub中，一个普通的仓库可能没有什么特别的，也许就是服务器上的一个文件夹。但是当仓库被其他人Fork的时候就不一样了，在执行Fork时，显然GitHub不会完整复制整个仓库。否则，同一个仓库在服务器上会占用双倍空间，这显然不合理。另外，想想Git的结构：它由提交对象和分支指针构成，每次提交都有唯一的Hash值且不会冲突。因此可以推测，GitHub在实现Fork时，所有被Fork的仓库可能共享同一个对象库，而每个用户仓库只保存指针，这样所有仓库只会占用增量空间，而不会存储重复内容。

但这样也会带来一个问题，首先因为很多人可能要共用一部分对象，所以也很难确认对象的所有权，而且也因为这个原因所有的对象要能被所有人访问。因此在整个Fork网络中，只要有一个仓库存在，GitHub就必须保留所有的对象，而且每个仓库都能访问这个网络中所有的对象。为了验证这一点，我们可以用最知名的Linux内核仓库做个示例。

首先对Linux仓库进行Fork，然后我们可以随便做一些改动，比如在README中写“Linux已经被我占领了😆”之类的内容，提交到自己的仓库，并且记下提交的Hash值，接下来就可以把自己的仓库删掉了。如果上面的猜想是正确的，那么在这个Fork网络中的任何一个仓库查看我刚刚的提交应该都可以，于是我直接在主仓库拼上了提交的Hash值（顺便一说只要值唯一，和其他的提交不冲突，短的Hash值也可以），果不其然能找到刚刚修改的内容，这样一来，只要GitHub和任意一个Linux仓库的Fork还存在，这个提交就永远存在了😝。

#
找回仓库

那么接下来找回之前网站的方案就很简单了，我只要找到网站仓库的任意一个Fork，然后只要知道最新的提交Hash，我就可以还原最新的仓库了。Fork倒是好找，随便搜一下就能找到一个。这个Fork的最新提交是2016年，但要想找到我当年演讲的版本至少到2018年之后。不过这个Hash值也不太好找，虽然理论上爆破短Hash值也可以，但是感觉太麻烦了，没有那个必要，所以我干脆直接去互联网档案馆看看能找到的最新的仓库页面吧，这样我就能找到它的Hash值了，然后我再把Fork仓库的地址和Hash拼到一起，就看得到最新代码了。

当然，仅仅看到代码还不够。我想Fork这个项目并在自己的GitHub Pages上部署一份。有没有什么好办法可以将我仓库的HEAD指针指向最新的提交呢？其实很简单，首先我要Fork这个Fork仓库，然后Clone我的仓库到本地。不过，此时Clone下来的仓库并不包含GitHub上完整的对象库，因此直接checkout或reset是不行的。这时Hash值就派上用场了，通过fetch拉取对应提交后，就可以进行上述操作。具体命令如下：

    git fetch origin <commit-hash>
    git reset --hard <commit-hash>
    git push origin master

最终我就获得了包含最新代码的Brainfuck可视化演示了🎉。

#
结局

后来我才知道，原来有一个专门的组织Software Heritage会保存所有代码，根本没必要搞这些花里胡哨的操作😂，像这个仓库也是能很轻易在上面找到，这下以后知道了，再遇到类似情况就可以直接去Software Heritage查找，而不必在互联网档案馆上找线索瞎折腾了🤣。

tags: GitHub - Git - 代码恢复 - 软件存档 查看原始文件

#### 推荐文章

Loading...

上一篇：关于ZIP Quine与自产生程序的探索
下一篇：让博客永恒的探索
想问这篇文章
召唤伊斯特瓦尔