将大型存储库拆分为多个子存储库并保留历史记录 (Mercurial)
我们拥有大量代码库,其中在 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 项目的文件夹。 Product1.sln 和 Product2.sln 都引用所有其他项目。理想情况下,我想获取每个文件夹,并将它们变成单独的 Hg 存储库,并为每个项目添加新的存储库(它们将充当父存储库)。然后,如果有人要处理 Product1,他们会克隆 Product1 存储库,其中包含 Product1.sln 以及对 ReferenceAssemblies、Core、Core.Tests、Database、Database.Tests、CMS 和 CMS.Tests 的子存储库引用。
因此,只需在项目目录中进行 hg 初始化即可轻松完成此操作。但能在保留历史的同时做到这一点吗?或者有更好的方法来安排吗?
编辑::::
感谢 Ry4an 的回答,我能够实现我的目标。我想与其他人分享我是如何做到这一点的。
由于我们有很多单独的项目,因此我编写了一个小型 bash 脚本来自动创建文件映射并创建最终的 bat 脚本来实际执行转换。从答案中不完全明显的是,转换命令需要为每个文件映射运行一次,以便为每个项目生成一个单独的存储库。该脚本将放置在您之前转换的 svn 工作副本上方的目录中。我使用了工作副本,因为它的文件结构最符合我想要的最终新 hg 存储库。
#!/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 工作副本中的每个文件,并根据类型创建一个新的文件映射文件或附加到现有文件。 if 实际上只是捕获杂项 Visual Studio 文件,并将它们放入单独的存储库中。这本来是要在 bash 上运行的(在我的例子中是 cygwin),但由于 Windows 上的分叉/进程问题,运行实际的转换命令是通过 TortoiseHg 附带的 hg 版本完成的(啊,我知道......)。
因此,您运行 MASTERGO.convert.bat 文件,该文件会查看转换后的 hg 存储库,并使用提供的文件映射创建单独的存储库。完成后,有一个名为 hg-separated 的文件夹,其中包含每个项目的文件夹/存储库,以及每个解决方案的文件夹/存储库。然后,您必须手动将所有项目克隆到解决方案存储库中,并将克隆添加到 .hgsub 文件中。提交后,将创建一个 .hgsubstate 文件,您就可以开始了!
根据上面给出的示例,“Product1”的 .hgsub 文件如下所示:
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
将这些存储库传输到中央服务器后,我将手动将路径更改为 url。
此外,没有与最初的 OurPlatform svn 存储库类似的东西,因为现在一切都是分开的。
再次感谢!
We have a large base of code that contains several shared projects, solution files, etc in one directory in SVN. We're migrating to Mercurial. I would like to take this opportunity to reorganize our code into several repositories to make cloning for branching have less overhead. I've already successfully converted our repo from SVN to Mercurial while preserving history. My question: how do I break all the different projects into separate repositories while preserving their history?
Here is an example of what our single repository (OurPlatform) currently looks like:
/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
All of those are folders containing VS Projects except for the solution files. Product1.sln and Product2.sln both reference all of the other projects. Ideally, I'd like to take each of those folders, and turn them into separate Hg repos, and also add new repos for each project (they would act as parent repos). Then, If someone was going to work on Product1, they would clone the Product1 repo, which contained Product1.sln and subrepo references to ReferenceAssemblies, Core, Core.Tests, Database, Database.Tests, CMS, and CMS.Tests.
So, it's easy to do this by just hg init'ing in the project directories. But can it be done while preserving history? Or is there a better way to arrange this?
EDIT::::
Thanks to Ry4an's answer, I was able to accomplish my goal. I wanted to share how I did it here for others.
Since we had a lot of separate projects, I wrote a small bash script to automate creating the filemaps and to create the final bat script to actually do the conversion. What wasn't completely apparent from the answer, is that the convert command needs to be run once for each filemap, to produce a separate repository for each project. This script would be placed in the directory above a svn working copy that you have previously converted. I used the working copy since it's file structure best matched what I wanted the final new hg repos to be.
#!/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/
This script looks at every file in an svn working copy, and depending on the type either creates a new filemap file or appends to an existing one. The if is really just to catch misc visual studio files, and place them into a separate repo. This is meant to be run on bash (cygwin in my case), but running the actual convert command is accomplished through the version of hg shipped with TortoiseHg due to forking/process issues on Windows (gah, I know...).
So you run the MASTERGO.convert.bat file, which looks at your converted hg repo, and creates separate repos using the supplied filemap. After it is complete, there is a folder called hg-separated that contains a folder/repo for each project, as well as a folder/repo for each solution. You then have to manually clone all the projects into a solution repo, and add the clones to the .hgsub file. After committing, an .hgsubstate file is created and you're set to go!
With the example given above, my .hgsub file looks like this for "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
Once I transfer these repos to a central server, I'll be manually changing the paths to be urls.
Also, there is no analog to the initial OurPlatform svn repo, since everything is separated now.
Thanks again!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这绝对是可以做到的。您需要使用
hg Convert
命令。这是我使用的过程:hg Convert
将所有内容转换为单个 hg 存储库,源类型为 svn ,目标类型为 hg (听起来您已经完成了此步骤hg Convert
的--filemap
选项一起使用的filemap
文件集合,hg Convert
hg
和 dest 类型hg
,源是在第一步中创建的 Mercurial 存储库 - 并对您在第二步中创建的每个文件映射执行此操作。文件映射语法显示在
hg help Convert
输出中,但要点如下:因此,在您的示例中,您的文件映射将如下所示:
请注意,如果您有一个包含,则暗示排除其他所有内容。此外,重命名行以点结尾,并将所有内容上移一级。
等等。
为每个新存储库创建了分解存储库后,您可以删除在第一步中创建的包含所有内容的初始存储库,并开始在
.hgsub
文件中设置子存储库配置。This can absolutely be done. You'll want to use the
hg convert
command. Here's the process I'd use:hg convert
with a source type of svn and a dest type of hg (it sounds like you've already done this step)filemap
files for use withhg convert
's--filemap
optionhg convert
with source typehg
and dest typehg
and the source being the mercurial repo created in step one -- and do it for each of the filemaps you created in step two.The filemap syntax is shown in the
hg help convert
output, but here's the gist:So in your example your filemaps would look like this:
Note that if you have an include that the exclusion of everything else is implied. Also that rename line ends in a dot and moves everything up one level.
and so on.
Once you've created the broken-out repositories for each of the new repos, you can delete the has-everything initial repo created in step one and start setting up your subrepo configuration in
.hgsub
files.