0

我的一位同事试图Diff.java从我们的 GitHub 存储库的历史记录中永久删除一个文件 ( )。

他有充分的理由想要这样做,但是似乎出了点问题,因为我们似乎丢失了很多文件,这些文件已被后缀为.REMOVED.git-id. 例如ivy-2.2.0.jar-> ivy-2.2.0.jar.REMOVED.git-id

我已经设法修复了主要的开发分支,因为我碰巧在本地有一个副本。然而,有许多开发线的历史分支和发布的标签现在似乎以上述方式被破坏。

我了解他运行的过程类似于:

$ git clone --mirror git://example.com/some-big-repo.git
$ java -jar bfg-1.12.3.jar --strip-biggest-blobs 500 some-big-repo
$ cd some-big-repo
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive
$ git push

$ cd ..
$ java -jar bfg-1.12.3.jar --delete-files Diff.java some-big-repo
$ cd some-big-repo
$ git push

我猜这个过程是破坏性的,除非在这发生之前我们碰巧在某个地方有一个干净的镜子,否则没有办法恢复。任何人都可以确认或提供一些建议吗?

4

1 回答 1

1

这是删除所有这些旧罐子的步骤:

$ java -jar bfg-1.12.3.jar --strip-biggest-blobs 500 some-big-repo

...作为 BFG 的作者,我很遗憾地意识到--strip-biggest-blobs 500并没有我想象的那么清楚。该命令从存储库历史记录中删除最大的 500 个文件(即大文件或二进制大对象:'blob')。我很想知道用户认为该步骤会做什么!

这是正确摆脱的命令Diff.java

$ java -jar bfg-1.12.3.jar --delete-files Diff.java some-big-repo

BFG的说明说“您应该在运行 BFG 之前对您的存储库进行备份,但听起来这里没有发生这种情况。

考虑到两件事,您可能仍然有机会恢复旧的分支和标签:

  1. 原始对象数据仍然可用的存储库。那将是您的本地副本,也可能是 GitHub,因为它们不会立即git gc存储库上运行 - 如果您使用它们,这些对象很可能仍然存在,甚至可能被旧的拉取请求引用。我会立即对您的 GitHub 存储库进行镜像克隆。
  2. 您还需要旧的 'ref' 值(原始分支和标记提交 ID)。您可以在本地副本的reflog或 CI 服务器的日志中找到它们。BFG 在命令行上打印出更改的 refs 的旧值和新值,但我猜你仍然没有那个输出。BFG 当前不保存该输出,但它每次运行时都会在目录下保存一个object-id-map.old-new.txt文件,其中包含旧 id 和新 id,用于它更改的每个提交。some-big-repo.bfg-report这些文件将不止一个,因为 BFG 运行了不止一次。使用这些文件,并检查您当前的refs,您应该能够回溯两次 BFG 运行以找出您的 refs 的原始提交 ID。

考虑到这些情况,您的恢复过程是这样的:

  • 克隆--mirror最有可能仍包含旧对象的存储库。
  • 测试它是否真的有这些对象。因此,假设您可以确定旧的 idmaster686b0cd80ac328e060b80dda3c9dadb1e400134a,do git cat-file -p 686b0cd80ac328e060b80dda3c9dadb1e400134a。如果对象仍然存在,您将看到提交的摘要。如果不是,请为您的其他候选存储库添加遥控器,并尝试从那里提取数据
  • 使用git update-refmaster分支设置为原始提交的值:git update-ref refs/heads/master 686b0cd80ac328e060b80dda3c9dadb1e400134a

对您关心的所有其他分支和标签重复此操作 - 希望您可以编写脚本,祝您好运!

于 2015-06-30T22:20:54.073 回答