我们有一大堆代码,在SVN的一个目录中包含多个共享项目,解决方案文件等。我们正在迁移到Mercurial。我想借此机会将我们的代码重新组织到几个存储库中,以便克隆分支的开销更少。我已经成功地将我们的回购从SVN转换为Mercurial,同时保留了历史。我的问题:如何在保留历史记录的同时将所有不同的项目分解为单独的存储库?
以下是我们的单一存储库(OurPlatform)目前的示例:
/OurPlatform
---- Core
---- Core.Tests
---- Database
---- Database.Tests
---- CMS
---- CMS.Tests
---- Product1.Domain
---- Product1.Stresstester
---- Product1.Web
---- Product1.Web.Tests
---- Product2.Domain
---- Product2.Stresstester
---- Product2.Web
---- Product2.Web.Tests
==== Product1.sln
==== Product2.sln
除解决方案文件外,所有这些文件夹都包含VS Projects。 Product1.sln和Product2.sln都引用了所有其他项目。理想情况下,我想采取每个文件夹,并将它们转换为单独的Hg回购,并为每个项目添加新的回购(它们将充当父回购)。然后,如果有人打算使用Product1,他们将克隆Product1 repo,其中包含Product1.sln和Subrepo对ReferenceAssemblies,Core,Core.Tests,Database,Database.Tests,CMS和CMS.Tests的引用。
因此,通过项目目录中的hg init'ing很容易做到这一点。但这可以在保存历史的同时完成吗?或者有更好的方法来安排这个吗?
EDIT ::::
感谢Ry4an的回答,我完成了目标。我想分享我在这里为其他人做的事情。
由于我们有很多单独的项目,我编写了一个小的bash脚本来自动创建文件图并创建最终的bat脚本来实际进行转换。从答案中不完全明显的是,convert命令需要为每个文件映射运行一次,以便为每个项目生成一个单独的存储库。此脚本将放在您先前转换的svn工作副本上方的目录中。我使用了工作副本,因为它的文件结构最符合我想要的最终新的hg repos。
#!/bin/bash
# this requires you to be in: /path/to/svn/working/copy/, and issue: ../filemaplister.sh ./
for filename in *
do
extension=${filename##*.} #$filename|awk -F . '{print $NF}'
if [ "$extension" == "sln" -o "$extension" == "suo" -o "$extension" == "vsmdi" ]; then
base=${filename%.*}
echo "#$base.filemap" >> "$base.filemap"
echo "include $filename" >> "$base.filemap"
echo "C:\Applications\TortoiseHgPortable\hg.exe convert --filemap $base.filemap ../hg-datesort-converted ../hg-separated/$base > $base.convert.output.txt" >> "MASTERGO.convert.bat"
else
echo "#$filename.filemap" >> "$filename.filemap"
echo "include $filename" >> "$filename.filemap"
echo "rename $filename ." >> "$filename.filemap"
echo "C:\Applications\TortoiseHgPortable\hg.exe convert --filemap $filename.filemap ../hg-datesort-converted ../hg-separated/$filename > $filename.convert.output.txt" >> "MASTERGO.convert.bat"
fi
done;
mv *.filemap ../hg-conversion-filemaps/
mv *.convert.bat ../hg-conversion-filemaps/
此脚本查看svn工作副本中的每个文件,并根据类型创建新的filemap文件或附加到现有文件。 if实际上只是为了捕获misc visual studio文件,并将它们放入一个单独的repo中。这是为了在bash上运行(在我的情况下是cygwin),但运行实际的转换命令是通过TortoiseHg附带的hg版本完成的,因为Windows上的分叉/进程问题(gah,我知道......)。
因此,您运行MASTERGO.convert.bat文件,该文件查看转换后的hg repo,并使用提供的文件映射创建单独的repos。完成后,有一个名为hg-separated的文件夹,其中包含每个项目的文件夹/存储库,以及每个解决方案的文件夹/存储库。然后,您必须手动将所有项目克隆到解决方案仓库中,并将克隆添加到.hgsub文件中。提交后,会创建一个.hgsubstate文件,你就可以开始了!
通过上面给出的示例,我的.hgsub文件对于“Product1”看起来像这样:
Product1.Domain = /absolute/path/to/Product1.Domain
Product1.Stresstester = /absolute/path/to/Product1.Stresstester
Product1.Web = /absolute/path/to/Product1.Web
Product1.Web.Tests = /absolute/path/to/Product1.Web.Tests
将这些存储库转移到中央服务器后,我将手动将路径更改为网址。
此外,最初的OurPlatform svn repo没有类似物,因为现在一切都已分开了。
再次感谢!
答案 0 :(得分:28)
这绝对可以做到。您将需要使用hg convert
命令。这是我使用的过程:
hg convert
将所有内容转换为单个hg存储库,源类型为svn,目标类型为hg(听起来您已完成此步骤)filemap
个文件的集合,以便与hg convert
的{{1}}选项一起使用--filemap
和目标类型hg convert
运行hg
,并且源是在第一步中创建的mercurial repo - 并为您在步骤中创建的每个文件图执行此操作2。 filemap语法显示在hg
输出中,但这里是要点:
hg help convert
因此,在您的示例中,您的文件映射将如下所示:
The filemap is a file that allows filtering and remapping of files and
directories. Comment lines start with '#'. Each line can contain one of
the following directives:
include path/to/file
exclude path/to/file
rename from/file to/file
请注意,如果您有一个包含,则隐含其他所有内容。此外,重命名行以点结尾,并将所有内容向上移动一级。
# this is Core.filemap
include Core
rename Core .
等等。
为每个新仓库创建分解存储库后,您可以删除在步骤1中创建的has-everything初始仓库,并开始在# this is Core.Tests
include Core.Tests
rename Core.Tests .
个文件中设置子备份配置。