是否可以使用 `git filter-repo` 从 git 存储库中删除特定版本的文件?

Is it possible to use `git filter-repo` to remove a specific version of a file from a git repository?

假设我有一个包含三个提交的小型 Git 存储库:

commit cccc:
    updated smile.png  (LFS)
    updated manual.md

commit bbbb:
    updated smile.png (LFS) <==== Don't want this specific one anymore!
    added manual.md

commit aaaa:
    added smile.png (LFS)
    added README.md
    added .gitattributes

我添加了 3 个不同版本的 LFS 文件 smile.png,但我确定我不希望或不需要中间版本再存在于我的存储库中。我不介意更改 git 历史记录。我还想缩小存储库的整体大小。

我知道 git filter-repo --path smile.png --invert-paths 可用于完全删除 smile.png 的所有实例和引用。但是,有没有办法从提交 bbbb 中删除特定版本,同时保留 aaaacccc 中的版本?

Git-LFS 的使用给原本非常简单的东西增加了一点小麻烦。

可以“删除”提交bbbb。为此,您还必须“删除”提交cccc。我在这里将“remove”放在引号中,因为 Git 实际上并没有 remove 提交。它只是把他们推到一边。它们会在您的存储库中保留一段时间,因此如果您认为“删除”它们是错误的,您可以取回它们。

它们保留多长时间——以及为什么——是一件有点复杂的事情,但默认情况下是将已删除的提交保留至少 30 天。同时,在删除 bbbb 时必须删除 cccc 的原因很简单:每个提交 取决于所有 previous[= 的存在 77=] 提交。所以你不能只是从链条的中间撕下一个。您必须删除那个 和所有后续提交 .

这意味着要保留提交cccc内容,您需要制作一个 cccc 的新改进版本。替换的新颖性是自动的:无法更改现有提交,但始终可以添加新提交。提交的改进之处在于它包含您想要的快照——无论您选择如何安排它——并且它链接回提交 aaaa。因此,在查看提交时,Git 现在将从最后一次提交 cccd(或其哈希 ID 是什么)开始并查看那个,然后返回 aaaa 并查看那个, 你会看到你喜欢的历史。

git filter-branchgit filter-repo都可以轻松完成这种手术。还有其他方法可以进行相同的手术;在这种特殊情况下,只需复制一个提交,我们就可以使用 git commit-tree(使新的和改进的 cccd)和 git reset(将分支名称移动到 find cccd),例如。请在此处查看关于编辑历史的许多 Whosebug 问题中的任何一个(git replace、commit-tree 方法、BFG、filter-branch、filter-repo 等)。

以下是使用 Git-LFS 的注意事项:当您在 Git-LFS 中添加并提交“大文件”时,LFS 软件已秘密地将您的文件替换为“LFS 指针文件”(很小:通常小于 1 KiB)。这意味着 Git 根本不会存储 你的文件 。 Git 存储此 LFS 指针文件。 LFS 代码已经将您的文件存储在其他地方(在其他网站上),1 并使用指针文件查找存储的文件。当你 Git 检查一些特定的提交时,Git-LFS 软件拦截检查,注意到一些文件已经被秘密替换为指针,然后去 LFS 网站检索大文件。

当您重写历史记录时,您将创建一个新提交 cccd,其 contentcccc 完全相同。这很好,因为 cccd 中的指针文件将是 cccc 中的指针文件。所以 LFS 拦截器将用相同的更大文件替换它。但是:提交 bbbb 包含指向存储在 other 网站上的某个文件的指针文件,其中保存了大文件。这个其他网站不知道您永远不会再次参考提交 bbbb2 所以他们将 keep 大文件。

如果你想让他们摆脱大文件的 for-bbbb 版本,你需要一些其他机制——一个完全在 Git 本身之外的机制——来摆脱它的。 Git 的任何部分都不会这样做。请注意,如果您专门使用 GitHub,您可能会遇到一些问题:


1这个“单独的网站”可以是主要的托管服务提供商网站,也可以是辅助网站,或者完全独立于某些托管服务提供商的网站。详细信息取决于您和您的 LFS 配置。

2假设,也就是说,你不改变主意,恢复提交bbbb