是否可以使用 `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
中删除特定版本,同时保留 aaaa
和 cccc
中的版本?
Git-LFS 的使用给原本非常简单的东西增加了一点小麻烦。
您可以“删除”提交bbbb
。为此,您还必须“删除”提交cccc
。我在这里将“remove”放在引号中,因为 Git 实际上并没有 remove 提交。它只是把他们推到一边。它们会在您的存储库中保留一段时间,因此如果您认为“删除”它们是错误的,您可以取回它们。
它们保留多长时间——以及为什么——是一件有点复杂的事情,但默认情况下是将已删除的提交保留至少 30 天。同时,在删除 bbbb
时必须删除 cccc
的原因很简单:每个提交 取决于所有 previous[= 的存在 77=] 提交。所以你不能只是从链条的中间撕下一个。您必须删除那个 和所有后续提交 .
这意味着要保留提交cccc
的内容,您需要制作一个 cccc
的新改进版本。替换的新颖性是自动的:无法更改现有提交,但始终可以添加新提交。提交的改进之处在于它包含您想要的快照——无论您选择如何安排它——并且它链接回提交 aaaa
。因此,在查看提交时,Git 现在将从最后一次提交 cccd
(或其哈希 ID 是什么)开始并查看那个,然后返回 aaaa
并查看那个, 你会看到你喜欢的历史。
git filter-branch
和git 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
,其 content 与 cccc
完全相同。这很好,因为 cccd
中的指针文件将是 cccc
中的指针文件。所以 LFS 拦截器将用相同的更大文件替换它。但是:提交 bbbb
包含指向存储在 other 网站上的某个文件的指针文件,其中保存了大文件。这个其他网站不知道您永远不会再次参考提交 bbbb
。2 所以他们将 keep 大文件。
如果你想让他们摆脱大文件的 for-bbbb
版本,你需要一些其他机制——一个完全在 Git 本身之外的机制——来摆脱它的。 Git 的任何部分都不会这样做。请注意,如果您专门使用 GitHub,您可能会遇到一些问题:
1这个“单独的网站”可以是主要的托管服务提供商网站,也可以是辅助网站,或者完全独立于某些托管服务提供商的网站。详细信息取决于您和您的 LFS 配置。
2假设,也就是说,你不改变主意,恢复提交bbbb
。
假设我有一个包含三个提交的小型 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
中删除特定版本,同时保留 aaaa
和 cccc
中的版本?
Git-LFS 的使用给原本非常简单的东西增加了一点小麻烦。
您可以“删除”提交bbbb
。为此,您还必须“删除”提交cccc
。我在这里将“remove”放在引号中,因为 Git 实际上并没有 remove 提交。它只是把他们推到一边。它们会在您的存储库中保留一段时间,因此如果您认为“删除”它们是错误的,您可以取回它们。
它们保留多长时间——以及为什么——是一件有点复杂的事情,但默认情况下是将已删除的提交保留至少 30 天。同时,在删除 bbbb
时必须删除 cccc
的原因很简单:每个提交 取决于所有 previous[= 的存在 77=] 提交。所以你不能只是从链条的中间撕下一个。您必须删除那个 和所有后续提交 .
这意味着要保留提交cccc
的内容,您需要制作一个 cccc
的新改进版本。替换的新颖性是自动的:无法更改现有提交,但始终可以添加新提交。提交的改进之处在于它包含您想要的快照——无论您选择如何安排它——并且它链接回提交 aaaa
。因此,在查看提交时,Git 现在将从最后一次提交 cccd
(或其哈希 ID 是什么)开始并查看那个,然后返回 aaaa
并查看那个, 你会看到你喜欢的历史。
git filter-branch
和git 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
,其 content 与 cccc
完全相同。这很好,因为 cccd
中的指针文件将是 cccc
中的指针文件。所以 LFS 拦截器将用相同的更大文件替换它。但是:提交 bbbb
包含指向存储在 other 网站上的某个文件的指针文件,其中保存了大文件。这个其他网站不知道您永远不会再次参考提交 bbbb
。2 所以他们将 keep 大文件。
如果你想让他们摆脱大文件的 for-bbbb
版本,你需要一些其他机制——一个完全在 Git 本身之外的机制——来摆脱它的。 Git 的任何部分都不会这样做。请注意,如果您专门使用 GitHub,您可能会遇到一些问题:
1这个“单独的网站”可以是主要的托管服务提供商网站,也可以是辅助网站,或者完全独立于某些托管服务提供商的网站。详细信息取决于您和您的 LFS 配置。
2假设,也就是说,你不改变主意,恢复提交bbbb
。