8

另请参阅此问题

在不知道自己在做什么的情况下,我启用了 largefiles 扩展,提交了一个文件并将其推送到 kiln。现在我知道我的方式的错误,我需要永久恢复这种变化。

我遵循了 SO 关于该主题的指导;我可以在本地删除大文件,但这不会影响窑中的远程仓库。我尝试在 Kiln 服务器上的 KilnRepositories 中打开 repo 并删除 largefiles 文件夹(以及从需要文件中删除“大文件”),但是在几次推/拉文件夹后,需要的行又回来了。

有没有办法让它永久化?(设置要求只读也不起作用)。

4

1 回答 1

12

注意:至少(对于 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 文件夹,克隆,无论您喜欢什么方法)。

最后,事实证明启用大文件是一个极其昂贵的错误。修复起来非常耗时,而且最终具有破坏性。我不建议您允许大文件进入您的存储库。

于 2013-03-21T00:11:45.060 回答