1

TL;DR 版本:是否可以在不破坏 Kiln/Fogbuz 历史的情况下重组 Mercurial 存储库?还是我必须重新开始?


我有一个非常混乱的存储库,需要进行一些认真的清理,并且正在尝试找出最好的方法。目标是完全删除一些文件——它们不应该出现在任何提交中,永远——移动一些目录,并将一个目录拆分到一个完全独立的存储库中。我知道,我知道——你不应该能够改变历史。但是,在这种情况下,它要么更改历史记录,要么从头开始使用新的存储库。

有问题的存储库在 Mercurial 中管理,远程存储库托管在Kiln中。在Fogbugz中跟踪问题。由于一些提交链接处理规则,提交消息中对问题(案例)编号的任何引用Case 123都将转换为指向相关 Fogbugz 案例的链接。反过来,提到的案例有一个附有提交消息的注释。

当前结构

项目文件结构目前是这样的:

- /
    +- includes/
    |   +- functions-related-to-abc.php
    |   +- functions-related-to-xyz.php
    |   +- class-something.php
    |   +- classes-several-things.php
    |   +- random-file.php
    |   ...
    |
    +- development/
    |   +- a-plugin-folder/
    |   |   +- some-file.php
    |   |   +- file-with-sensitive-and-non-sensitive-info.php
    |   |   ...
    |   |
    |   +- some-backend-functions-related-to-coding.php
    |   ...
    |
    +- index.php
    +- test-config-file.php
    ...

目标结构

我想要的结构是这样的:

- /
    +- build/
    +- doc/
    +- src/
    |   +- functions/
    |   |   +- abc.php  // renamed from includes/functions-related-to-abc.php
    |   |   +- xyz.php  // renamed from includes/functions-related-to-xyz.php
    |   |   ...
    |   |
    |   +- classes/
    |   |   +- something.php       // renamed from includes/class-something.php
    |   |   +- several-things.php  // renamed from includes/classes-several-things.php
    |   |   ...
    |   |
    |   +- view/
    |   |   +- random-file.php  // formerly includes/random-file.php
    |   ...
    |
    |   +- development/
    |   |   +- some-backend-functions-related-to-coding.php
    |   |   ...
    |   +- index.php
    |   ...
    |
    +- test/
    ...

a-plugin-folder将移至其自己的单独存储库。test-config-file.php将不再在存储库中进行跟踪。理想情况下,我还会对分支进行一些小的修剪和重命名。

在我的梦想世界中,file-with-sensitive-and-non-sensitive-info.php会以某种方式始终如一地被跟踪,但是敏感信息(几个密码)被拉到一个不受版本控制的配置文件中。我意识到这可能是一厢情愿的想法。

我目前的想法

我目前的想法是,我的愿望清单基本上是不可能的:从现在开始,我可以创建新的、结构合理的存储库,但不能保留我的更改历史记录,也无法进行我需要进行的根本性结构更改。在这个视图中,我应该使用当前的代码库,按照我想要的方式重新组织它,并将它作为变更集 1 提交给两个新的存储库(根存储库和插件存储库)。然后,我会在某处备份旧存储库的副本以供参考。主要缺点:(1) 我丢失了所有历史记录,(2) Kiln 和 Fogbugz 对历史提交的交叉引用都是吐司。

我的问题

所以,问题来了:有什么方法可以做我想做的事——重组,拉出一些文件,让一切看起来很漂亮——而不丢失我所有的历史?

我考虑过使用hg convert扩展名,大量使用filemap,splicemapbranchmap选项。我用这种方法看到的问题包括:(1) 破坏所有先前的构建,(2) 根本没有file-with-sensitive-and-non-sensitive-info.php先前的构建(或将其留在里面,这会破坏这一点),以及 (3) 大量渲染许多提交消息在他们引用文件名或 repo 结构的程度上是不正确的。换句话说,与刚开始干净、结构合理的存储库相比,我不确定这个选项对我有多大帮助。

我还考虑过极端的选择:编写某种自定义脚本来构建一个新的存储库,方法是遍历每个现有的提交,从 中剥离敏感信息,file-with-sensitive-and-non-sensitive-info.php在必要的范围内重写提交消息,并提交所有内容的修订版本。从理论上讲,这可以解决我所有的问题,但代价是重新发明轮子并且可能要花费大量时间。我正在寻找不等同于编写整个hg扩展的东西。

编辑:我正在考虑创建一个空的存储库,然后编写一个脚本,一次使用hg exporthg import带来一个变更集,在必要时进行编辑以从文件中去除密码等敏感信息。有没有理由这不起作用?

4

2 回答 2

1

编辑:我最终采用了与下面描述的方法不同的方法。我的另一个答案解释了我最终做了什么。也就是说,我仍然对像下面描述的插件非常感兴趣,所以如果我有时间去做或者其他人想要承担这个项目,我会留下这篇文章以供参考。


我已经确定可以在存储库历史的适当位置使用导入、导出和一些补丁来实现这一点。

算法

该算法的简短版本如下所示:

  1. 创建一个新的存储库
  2. 遍历现有存储库的变更集,执行以下操作:

    1. 从旧存储库中导出变更集
    2. 将变更集导入新存储库而不提交
    3. 对提交消息和/或敏感文件进行任何必要的编辑
    4. 在新存储库中提交变更集,保留(可能已修改的)提交消息和其他元数据
  3. 交换新旧存储库

注意事项:

  • 显然,与所有历史编辑一样,这仅适用于未被第三方提取的非公共存储库。
  • 第 2 步可以而且应该高度自动化,无需编辑即可批量处理变更集。
  • 每当需要更改时,都必须停止执行。

让它工作

我有一个非常基本的概念证明批处理文件,证明这可以工作。

我正在开发一个 Mercurial 插件,以使其尽可能简单。也就是说,如果有人有更好的建议,我仍然愿意接受。

于 2014-03-22T04:54:58.347 回答
0

我能够实现我的目标。这就是我最终做的事情:

  • 首先,我通过消除所有分支和合并并将 repo 变成单行提交来“扁平化”(拉直)存储库。我必须这样做是因为hg histedit——整个清理的关键——不适用于包含合并的历史记录。这对我来说没问题,因为在这个特定的存储库中没有真正有意义的分支或合并,并且相关历史中只有一位作者。我可能会保留分支并在以后根据需要再次合并,但这对我的目的来说更容易。为此,我使用hg rebase了 MQ 扩展。(特别感谢@tghw 提供了这个非常有用的答案,它帮助我第一次了解了 MQ 的真正工作原理。)

  • 接下来,我曾经hg convert从原始存储库创建多个存储库——一个用于我需要放入其自己的存储库的每个库/插件,一个用于其余代码的主存储库。在此过程中,我使用--filemap--branchmap根据需要重新组织所有内容。

  • 第三,我hg histedit在每个新存储库上使用了 (1) 根据需要清理不相关的提交消息和 (2) 删除敏感信息。

  • 第四,我将所有新存储库推送到 Kiln,它使用与原始存储库相同的规则自动将它们链接到 FogBugz 案例(例如,Case 123在提交消息中创建到 FogBugz 案例 #123 的链接)。

  • 最后,我“删除”了 Kiln 中的原始存储库。Kiln 目前还没有真正永久地删除存储库,尽管我已经提出了一个使之成为可能的用例。相反,它会断开 FogBugz 案例的链接并将“已删除”的存储库放入冷存储;帐户管理员可以恢复它,但它是不可见的。

总而言之,将原始存储库分成 6 个部分并清理其中的每个部分大约需要 10 个小时。其中一些是学习曲线;如果我必须再做一次,我可能会在 6 个小时内完成整个事情。漫长的一天,但对于显着改进的存储库结构和清理的代码来说是值得的。

现在一切都应该如此。希望这将有助于其他用户。如果您有类似的问题并希望从我的经验中获得更多见解,请随时发表评论。

于 2014-06-08T17:52:34.933 回答