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交叉引用都是吐司。
所以,问题是:有没有办法做我想做的事情 - 重组,拉出一些文件,让一切看起来很漂亮 - 而不会失去我的所有历史记录? < / p>
我考虑过使用the hg convert
extension,大量使用filemap
,splicemap
和branchmap
选项。我在这种方法中遇到的问题包括:(1)打破所有先前的构建,(2)在先前的构建中根本没有file-with-sensitive-and-non-sensitive-info.php
(或者将其留在,这会使得点失败),以及(3)渲染许多提交消息在引用文件名或repo结构的范围内非常不正确。换句话说,我不确定这个选项能否让我获得更多,而不仅仅是启动干净,结构合理的存储库。
我还考虑了极端的选择:编写某种自定义脚本,通过遍历每个现有提交来构建新的存储库,从file-with-sensitive-and-non-sensitive-info.php
中剥离敏感信息,在必要的范围内重写提交消息,以及提交一切的修订版本。从理论上讲,这可以解决我的所有问题,但代价是重新发明轮子,可能需要花费大量时间。我正在寻找的东西不等于编写整个hg
扩展名。
编辑:我正在考虑创建一个空存储库,然后编写一个使用hg export
和hg import
的脚本,一次更改一个变更集,并在必要时进行编辑从文件中删除密码等敏感信息。这有什么原因不起作用吗?
答案 0 :(得分:1)
编辑:我最终采用了与下述方法不同的方法。 My other answer解释了我最终做的事情。也就是说,我仍然对下面描述的插件非常感兴趣,所以如果我有时间做这件事,或者其他任何人想要参与该项目,我将把这篇文章留作参考。
我已经确定在存储库的历史记录中的适当位置使用导入,导出和一些修补是可能的。
算法的简短版本如下所示:
循环遍历现有存储库的更改集,执行以下操作:
交换旧的和新的存储库
我有一个非常基本的概念验证批处理文件,证明这可以工作。
我正在使用Mercurial插件,以尽可能简化。也就是说,如果有人有任何建议,我仍然愿意接受更好的建议。
答案 1 :(得分:0)
我能够实现我的目标。这就是我最终做的事情:
首先,我&#34;被淘汰出局&#34; (拉直)存储库通过消除所有分支和合并并将repo转换为单行提交。我必须这样做,因为hg histedit
- 整个清理的关键 - 不适用于包含合并的历史记录。这对我来说没问题,因为在这个特定的存储库中没有真正有意义的分支或合并,并且相关历史记录中只有一位作者。我可能已经保留了分支并在以后需要时再次合并,但这对我来说更容易。为此,我使用了hg rebase
和MQ扩展。 (特别感谢@tghw for this extremely helpful answer,这有助于我第一次理解MQ的真正作用。)
接下来,我使用hg convert
从原始存储库创建多个存储库 - 每个库/插件需要放入一个存储库,另一个存储库用于其余代码。在此过程中,我使用--filemap
和--branchmap
根据需要重新组织了所有内容。
第三,我在每个新存储库上使用hg histedit
来(1)根据需要清理不相关的提交消息,以及(2)删除敏感信息。
第四,我将所有新存储库推送到Kiln,后者使用与原始存储库相同的规则自动将它们链接到FogBugz案例(例如,提交消息中的Case 123
创建FogBugz案例#123)的链接。
最后,我删除了&#34;窑中的原始存储库。尽管我已经提出了一个用于实现这一目的的用例,但Kiln目前还没有真正永久地删除存储库。相反,它将FogBugz案例脱钩并将&#34;删除&#34;存储库进入冷库;帐户管理员可以恢复它,但它是不可见的。
总而言之,将原始存储库分成6块并清理其中的每一部分花了大约10个小时。其中一些是学习曲线;如果我不得不再做一次,我可能会在6个小时内完成所有事情。漫长的一天,但值得大大改进的存储库结构和清理代码。
现在一切都应该如此。希望,这将有助于其他用户。如果您有类似的问题,请随时发表评论,并希望从我的经验中获得更多见解。