可以撤消永久删除文件吗?

时间:2015-06-30 15:12:51

标签: git-rewrite-history bfg-repo-cleaner

我的一位同事试图从我们的GitHub回购历史中永久删除文件(Diff.java)。

他有充分的理由想要这样做,但是似乎出现了一些错误,因为我们似乎已经丢失了很多文件,这些文件已经被后缀为.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

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

1 个答案:

答案 0 :(得分:0)

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

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

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

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

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

在运行BFG之前,

instructions for the BFG“你应该做一个备份你的存储库,但听起来这并没有发生在这里。

您可能仍有机会恢复旧的分支和标签,给出两件事:

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

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

    对你关心的所有其他分支和标签重复 - 希望你能编写脚本,祝你好运!