【问题标题】:Mercurial Repo Living ArchiveMercurial 回购生活档案
【发布时间】:2018-08-20 16:53:27
【问题描述】:

我们有一个超过 6GB 的 Hg 存储库和 150,000 个变更集。它在大型应用程序上已有 8 年的历史。在过去的 8 年中,我们使用了分支策略。在这种方法中,我们为功能创建一个新分支,完成后关闭分支并将其合并到默认/主干。在将更改推送到默认值后,我们不会修剪分支。

随着我们的 repo 增长,使用它变得越来越痛苦。我们喜欢拥有每个文件的完整历史记录,并且不想丢失它,但我们想让我们的 repo 大小更小。

我一直在研究的一种方法是拥有两个独立的存储库,一个“工作”存储库和一个“存档”存储库。工作回购将包含最近 1 到 2 年的历史,并且将是回购开发人员每天克隆和推/拉的。 Archive repo 将包含完整的历史记录,包括推送到工作 repo 中的新变更集。

我找不到正确的 Hg 命令来启用它。我能够使用hg convert <src> <dest> --config convert.hg.startref=<rev> 创建一个工作存储库。然而,Mecurial 认为这是一个完全不同的存储库,打破了工作存储库和存档存储库之间的任何关联。我无法找到将推送到工作存储库的变更集合并/拼接到存档存储库并维护统一文件历史记录的方法。我尝试了hg transplant -s <src>,但这导致了几个“跳过清空变更集”消息。我不清楚为什么hg transplant 命令感觉这些变更集是空的。另外,如果我要让这个工作,有谁知道它是否维护文件的历史,或者我的 repo 是否会将移植的部分视为单独的,可能显示为删除/创建或其他内容?

任何人都有解决方案来启用这种工作/存档方法或有可能对我们有用的不同方法?保持完整的文件历史记录对于简化历史研究至关重要。

谢谢

【问题讨论】:

  • 你好 Bryan,你能详细说明为什么你想让 repo 更小吗?是因为克隆太慢了吗?是不是因为某些操作太慢了(commit、push、pull)? Mercurial 最近有一些实验性更改可以帮助您,但首先我需要有关您的存储库的更多信息。你能运行hg heads -T "\n" | wc -l,它会给出你的存储库上的开放头数吗?

标签: mercurial repository


【解决方案1】:

您可能遇到了底层存储压缩的已知错误。 150,000 次修订需要 6GB。

此存储问题通常在非常分支的存储库中遇到,在存储每个修订内容的内部数据结构上。此错误的当前修复可以将存储库大小减少多达十倍。

可能的快速修复

您可以盲目地尝试对问题应用当前修复,看看它是否会缩小您的存储库。

  • 升级到 Mercurial 4.7,
  • 将以下内容添加到您的存储库配置中:

    [格式] sparse-revlog = 是的

  • 运行hg debugupgraderepo --optimize redeltaall --run(这需要一段时间)

4.7 中还默认启用了其他一些改进。所以升级到 4.7 并运行 debugupgraderepo 应该在所有情况下都有帮助。

更精细的诊断

你能告诉我们.hg/store/00manifest.d 文件的大小与.hg/store 的完整大小相比是多少?

另外,能否提供hg debugrevlog -m的输出使用

其他原因?

存储库大小增加的另一个原因是要在其中提交大型(通常是二进制文件)。你有吗?

【讨论】:

  • 我们确实有机会升级到 Mercurial 4.7。今晚我将与 debugupgraderepo 命令一起尝试。我也会看看能否获得您在更精细诊断中请求的其他信息。我们没有大量的二进制文件。我们有一些图像资产,但其中大部分是原始代码。我们只是有很多开发人员在做一个大型项目,我们喜欢称之为“超级应用”
【解决方案2】:

问题是每个修订的哈希 id 是根据包括父 id 在内的许多项目计算的。因此,当您更改父级时,您会更改 id。

据我所知,没有很好的方法可以做到这一点,但我对我的几个 repos 做了类似的事情。坏消息是,它需要一系列 repos、批处理文件和拼接图才能完成。

我所描述的大部分工作最好只完成一次,然后每次您想要更新它以获取最新提交时,您只需针对相同的现有存储库运行相同的脚本。


我会这样做的方式是拥有三个 repos:

  • 工作
  • 合并
  • 存档

Working 的第一次提交是 Archive 中所有原始提交的压缩,因此当您将 Working 代码拉入 Archive 时,您将丢弃该提交,并将第二次 Working 提交重新设置为 Archive 的旧提示.

停止:如果您要这样做,请在尝试之前备份您现有的存储库,尤其是存档存储库,如果您在其顶部运行它可能会被丢弃。也可以,不过我的良心没有问题!

  1. 将 Working 和 Archive 都拉入 Merge repo。
    您现在有一个合并存储库,其中包含两个完全独立的树。

  2. 创建拼接图。这只是一个文本文件,给出了一个子节点的哈希值和它提议的父节点的哈希值,用空格分隔。
    因此,您的拼接图将类似于:
    hash-of-working-commit-2 hash-of-archive-old-tip

  3. 然后使用 splicemap 选项运行 hg convert 以将 Working 的第二次提交重新设置为 Archive 的旧提示。例如
    hg convert --splicemap splicemapPath.txt --config convert.hg.saverev=true Merge Archive
    您可能想第一次尝试将其写入另一个命名的存储库而不是存档,或者您可以尝试将其写入现有存档的副本,我不确定它是否会工作,但如果可以的话,它可能会快点。

一旦您运行此设置一次,您就可以一次又一次地在现有存储库上运行相同的脚本,以使用最新的工作修订进行更新。只需从 Working 中拉取 Merge,然后运行 ​​hg convert 将其放入 Archive。

【讨论】:

  • @BorisFeld,我不确定该评论是否已添加到正确答案中,我没有提到回购大小。
猜你喜欢
  • 2011-03-03
  • 1970-01-01
  • 2011-05-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-06-08
相关资源
最近更新 更多