注意:至少(对于 Windows)TortoiseHg 2.4 (Mercurial 2.2.1) -> 2.7.1 (Mercurial 2.5.2) 是这样。我不会为未来或旧版本发言。
在查看了各种可用的 mercurial 扩展之后,我得出的结论是,一旦使用 largefiles 扩展提交了文件,通常就不可能将存储库“转换回”。
首先,为什么您不希望在您的存储库中使用大文件的两个基本原理:一和二。
一旦文件被提交为大文件,要删除它,必须从 repo 中删除对“.hglf”路径的所有引用。回退是不够的,因为它的提交内容将引用文件的路径,包括“.hglf”文件夹。一旦 mercurial 看到这一点,它会将“大文件”写回 /.hg/requires 文件,并且 repo 再次被大文件锁定。同样与 hg 忘记并删除。
选项 1:如果您的 repo 是孤立的(您可以在其所有本地和远程位置对 repo 进行端到端控制,并且没有其他人从该 repo 分支),则可以使用 mq 扩展和剥离变更集。如果您及时发现了错误,这可能只是一个可行的选择。
选项 2:如果有问题的变更集(大文件提交)存在于草稿的提交阶段(或者可以强制回到草稿),那么可以将提交导入 mq 并使用 hg qpop取消应用变更集。这优于剥离,因为它保留了提取变更集的提交历史。在现实生活中,这通常是不可能的,因为您可能已经执行了合并并从公共阶段分支推/拉。但是,如果及时发现,mq 可以提供一种挽救回购的方法。
选项 3:如果有问题的变更集仅在一处引用(原始提交),并且没有人尝试退出/删除/忘记变更集(从而创建多个引用),则可以使用 hg rebase,将攻击后的第一个子变更集与攻击的父变更集折叠起来。这样做时,进攻性变更集变成了一个新的头,然后可以用 mq strip 剥离。这可以在尝试导入 mq 失败的情况下工作。
选项 4:如果以上都不起作用,您可以使用移植或移植,将所有非违规变更集导出为补丁(注意以正确的顺序导出它们),然后 hg update 到攻击前的第一个健全的变更集, mq 剥离所有前向变更集的 repo,然后按顺序重新应用导出的补丁。
选项5:(我最终做了什么)。在本地克隆 repo,这样你就有两个副本:clone_to_keep、clone_to_destroy。在 clone_to_keep 中,更新到攻击前的第一个健全的变更集。Mq 剥离所有前向变更集。如果留下多个头,则向下合并。在 clone_to_destroy 中,更新到提示。在 Windows 资源管理器中,将 /clone_to_destroy 中除 .hg 和 .hglf 文件夹之外的所有内容复制到 /clone_to_keep 文件夹。在 Tortoise 中,将 clone_to_keep 中的所有更改提交为单个更改集。出于历史目的,将 clone_to_destroy 的一个远程实例保留为只读状态,并销毁所有其他实例。
选项 6:核选项。如果一切都失败了,并且您不关心您的存储库与外部系统的集成(错误跟踪、CI 等),您可以按照上述SO 帖子并使用 hg convert扩展。这将创建受感染存储库的新副本,删除对有问题的变更集的所有引用;但是,它通过迭代整个 repo 中的每个变更集并将其作为 NEW 变更集提交到新 repo 来实现。这会创建一个与任何现有分支 repos 不兼容的 repo——没有一个变更集 id 将排队。除非您没有分支存储库,否则此选项可能永远不会起作用。
在所有情况下,您都必须进行修复并手动重新应用到每个不同的存储库实例(复制 repo 文件夹,克隆,无论您喜欢什么方法)。
最后,事实证明启用大文件是一个极其昂贵的错误。修复起来非常耗时,而且最终具有破坏性。我不建议您允许大文件进入您的存储库。