简体   繁体   English

如何从Mercurial repo中删除largefiles

[英]How to remove largefiles from Mercurial repo

See also this question . 另见这个问题

Without knowing what I was doing, I enabled the largefiles extension, committed a file and pushed it to kiln. 在不知道我在做什么的情况下,我启用了largefiles扩展,提交了一个文件并将其推送到了窑中。 Now I know the error of my ways, and I need to permanently revert this change. 现在我知道我的方式的错误,我需要永久地恢复这种变化。

I followed the guidance from SO on the subject; 我遵循了SO关于这个主题的指导; and I can remove largefiles locally, but this doesn't affect the remote repos in kiln. 我可以在本地删除大文件,但这不会影响窑中的远程回购。 I have tried opening the repo in KilnRepositories on the Kiln server and nuking the largefiles folder (as well as deleting 'largefiles' from the requires file), but after a few pushes/pulls the folder and the require's line come back. 我试过在Kiln服务器上打开KilnRepositories中的repo并修改largefiles文件夹(以及从requires文件中删除'largefiles'),但是几次推/拉后文件夹和require的行返回。

Is there a way to make this permanent? 有没有办法让这个永久? (Setting requires to readonly doesn't work either). (设置要求readonly也不起作用)。

Note: This is true at least of (for Windows) TortoiseHg 2.4 (Mercurial 2.2.1) -> 2.7.1 (Mercurial 2.5.2). 注意:至少(对于Windows)TortoiseHg 2.4(Mercurial 2.2.1) - > 2.7.1(Mercurial 2.5.2)都是如此。 I will not speak for future or older versions. 我不会代表未来或旧版本。

After looking through the various mercurial extensions available, I have concluded that it is generally not possible to convert a repository 'back' once a file has been committed using the largefiles extension. 在查看了可用的各种mercurial扩展之后,我得出结论,一旦使用largefiles扩展提交文件,通常无法将存储库“返回”。

First, the two rationales for why you do not want largefiles in play on your repos: one and two . 首先,为什么你不希望在你的回购中使用大文件的两个理由:

Once a file has has been committed as a largefile, to remove it, all references to the '.hglf' path must be removed from the repo. 一旦文件已作为大文件提交,要删除它,必须从repo中删除对“.hglf”路径的所有引用。 A backout isn't sufficient, as its commit contents will reference the path of the file, including the '.hglf' folder. 退出是不够的,因为其提交内容将引用文件的路径,包括'.hglf'文件夹。 Once mercurial sees this, it will write 'largefiles' back to the /.hg/requires file and the repo is once more largefile locked. 一旦mercurial看到这个,它会将'largefiles'写回/.hg/requires文件,并且repo再次被大文件锁定。 Likewise with hg forget and remove. 同样用hg忘记并删除。

Option 1: If your repo is in isolation (you have end-to-end control of the repo in all of its local and remote locations AND no one else has branched from this repo), it may be possible to use the mq extension and strip the changeset. 选项1:如果您的仓库处于孤立状态(您在其所有本地和远程位置都有对仓库的端到端控制,并且没有其他人从该仓库分支),则可以使用mq扩展和剥离变更集。 This is probably only a viable option if you have caught the mistake in time. 如果你及时发现错误,这可能只是一个可行的选择。

Option 2: If the offending changeset (the largefile commit) exists on a commit phase that is draft (or that can be forced back into draft), then it may be possible to import the commit to mq and unapply the changeset using hg qpop. 选项2:如果违规变更集(大文件提交)存在于草稿提交阶段 (或者可以强制退回草稿),则可以将提交导入mq并使用hg qpop 取消应用变更集 This is superior to stripping, because it preserves the commit history forward from the extracted changeset. 这优于剥离,因为它从提取的变更集中保留了提交历史记录。 In real life, this is frequently not possible, because you've likely already performed merges and pushed/pulled from public phase branches. 在现实生活中,这通常是不可能的,因为您可能已经执行了合并并从公共阶段分支推送/拉出。 However, if caught soon enough, mq can offer a way to salvage the repo. 但是,如果抓住很快,mq可以提供一种方法来挽救回购。

Option 3: If the offending changeset is referenced in one and only one place (the original commit), and no one has attempted to backout/remove/forget the changset (thus creating multiple references), it may be possible to use hg rebase , to fold the first child changeset after the offense with the parent changeset of the offense. 选项3:如果在一个且只有一个地方(原始提交)引用了违规变更集,并且没有人试图退出/删除/忘记变更集(从而创建多个引用),则可以使用hg rebase ,使用攻击的父变更集在攻击后折叠第一个子变更集。 In doing so, the offensive changeset becomes a new head which can then be stripped off with mq strip. 在这样做的过程中,进攻性的变化组成了一个新的头部,然后可以用mq条剥离。 This can work where attempts to import to mq have failed. 这可以在导入到mq的尝试失败时起作用。

Option 4: If none of the above work, you can use transplant or graft , to export all of the non-offending changesets as patches (careful to export them in the correct sequence), then hg update to the first sane changeset before the offense, mq strip the repo of all forward changesets and then reapply your exported patches in sequence. 选项4:如果以上都不起作用,您可以使用移植移植 ,将所有非违规变更集导出为补丁(小心以正确的顺序导出它们),然后在攻击之前更新为第一个合理的变更集,mq去除所有前向变更集的回购,然后按顺序重新应用导出的补丁。

Option 5: (What I ultimately did). 选项5 :(我最终做了什么)。 Clone the repo locally, so that you have two copies: clone_to_keep, clone_to_destroy. 在本地克隆repo,以便有两个副本:clone_to_keep,clone_to_destroy。 In clone_to_keep, update to the first sane changeset before the offense. 在clone_to_keep中,在攻击之前更新到第一个合理的变更集。 Mq strip all forward changesets. Mq剥离所有前向变更集。 Merge back down if left with multiple heads. 如果留下多个头,则向下合并。 In clone_to_destroy, update to the tip. 在clone_to_destroy中,更新到提示。 In windows explorer, copy everything in /clone_to_destroy except the .hg and .hglf folders to the /clone_to_keep folder. 在Windows资源管理器中,将/ clone_to_destroy中的所有内容(.hg和.hglf文件夹除外)复制到/ clone_to_keep文件夹中。 Inside Tortoise, commit all changes in clone_to_keep as a single changeset. 在Tortoise内部,将clone_to_keep中的所有更改作为单个变更集提交。 Preserve one remote instance of clone_to_destroy in a readonly state for historical purposes, and destroy all others. 出于历史目的,将read_ly状态的clone_to_destroy的一个远程实例保留,并销毁所有其他实例。

Option 6: The nuclear option. 备选案文6:核选择。 If all else fails, and if you don't care about the integration of your repo with external systems (bug tracking, CI, etc), you can follow the aforementioned SO post and use the hg convert extension. 如果所有其他方法都失败了,如果您不关心将repo与外部系统集成(错误跟踪,CI等),您可以按照上述SO帖子并使用hg convert扩展。 This will create a new copy of the infected repo, removing all references to the offending changesets; 这将创建受感染仓库的新副本,删除对违规变更集的所有引用; however, it does so by iterating each changeset in the entire repo and committing it to the new repo as a NEW changeset. 但是,它通过迭代整个仓库中的每个变更集并将其作为新变更集提交给新仓库来实现。 This creates a repo which is incompatible with any existing branch repos--none of the changeset ids will line up. 这会创建一个与任何现有分支回购不兼容的仓库 - 任何变更集ID都不会排成一行。 Unless you have no branch repos, this option will probably never work. 除非你没有分支回购,否则这个选项可能永远不会有效。

In all cases, you then have to take your fix and manually reapply to each distinct repository instance (copy the repo folder, clone, whatever your preferred method). 在所有情况下,您必须采取修复并手动重新应用到每个不同的存储库实例(复制repo文件夹,克隆,无论您的首选方法)。

In the end, it turns out that enabling largefiles is an extremely expensive mistake to make. 最后,事实证明,启用大文件是一个非常昂贵的错误。 It's time consuming and ultimately destructive to fix. 这很费时间并且最终具有破坏性。 I don't recommend ever allowing largefiles to make it into your repos. 我不建议允许大文件进入你的回购。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM