R..*_*R.. 10 git version-control mercurial mercurial-subrepos
尽管涉及两个子部分,但我认为这是一个综合问题,因为它被分解成部分的方式并不重要.只要最终结果保留了所有有意义的历史记录以及检查,研究和构建/测试历史版本的能力,我就会以不同的方式实现我想要的目标.目标是退出hg和到目前为止使用的subrepo模型,然后转移到git中的统一树,但不会牺牲历史记录.
我开始的是一个Mercurial存储库,它包含一些顶级代码和许多有趣历史所在的子存储库.subrepos有一些分支/合并,但没有什么太疯狂.我想要实现的最终结果是单个git存储库,没有子模块,这样:
对于原始顶级hg repo中的每个提交,都有一个git提交,它会检查完全相同的树,因为您将检查相应的hg提交及其所有引用subrepo提交.
这些对应于连续顶级hg提交的git提交是彼此的后代,其提交对应于其间的所有相关子提交.
我对如何实现这一点的基本思想是迭代所有顶级hg提交,并且对于每个更改的顶级提交.hgsubstate,也迭代从旧修订到子模块的新修订的所有路径(可能涉及分枝).在每一步:
git-write-tree和git-commit-tree生成具有所需父级的提交,使用来自相应hg提交的authors,date和commit消息.这有用吗?有没有更好的方法来实现我想要的,也许首先用hg做subrepo崩溃?我不清楚的最重要的事情是如何执行所需的迭代,所以如何实现它的实用建议将是伟大的.
一个额外的约束:原始存储库涉及无法发布的内容(这是git-filter-branch基本转换完成后的额外步骤)所以涉及上传存储库以供第三方处理的解决方案是不可行的.
你所写的内容可能会或可能不会解决问题.但这并不简单.主要问题是您需要按顺序提交,以便您的子目录和主仓库保持一致.我以小规模重新创建了这个问题,并且能够在subrepos之间保持一致性).
我的解决方案
使用hg convert扩展,我将主repo转换为repo而没有subrepos(和相关信息).
cd main
awk '{ print $1}' .hgsub | xargs -n 1 echo 'exclude' > ../filemap
echo exclude .hgsub >> ../filemap
echo exclude .hgsubstate >> ../filemap
cd ..
hg convert --filemap filemap main mainConv
cd mainConv
hg update
Run Code Online (Sandbox Code Playgroud)使用--filemap中的重命名转换subrepo.
cd ..
echo rename . subRepo > subFileMap
hg convert --filemap main/subRepo subRepoConv
cd subRepoConv
hg update
Run Code Online (Sandbox Code Playgroud)将subrepos拉到转换后的主仓库.
cd ../mainConv
hg pull -f ../subRepoConv
Run Code Online (Sandbox Code Playgroud)在拉动时你会注意到回购中的多个头(因为subrepo有他们自己的头).合并他们:
hg heads
hg merge <RevID from subrepo (not main repo)>
hg ci -mMergeOfSubRepo
Run Code Online (Sandbox Code Playgroud)你必须为每个subrepo重复3和4.
但是提交不会被排序.所以按照这里的顺序将它们按顺序放入/sf/answers/1120881821/:
cd ..
hg clone -r 0 mainConv mainOrdered
cd mainOrdered
for REV in `hg log -R ../main -r 'sort(1:tip, date)' --template '{rev}\n'`
do
hg pull ../main -r $REV
done
Run Code Online (Sandbox Code Playgroud)现在使用http://repo.or.cz/w/fast-export.git将这个有序的mercurial repo转换为git :
cd ..
git clone git://repo.or.cz/fast-export.git
git init mainGit
cd mainGit
../fast-export/hg-fast-export.sh -r ../mainOrdered
git checkout HEAD
Run Code Online (Sandbox Code Playgroud)
无关的题外话
我确信,您选择了最糟糕的迁移想法(从 Mercurial 到 Git),但最终这是您的选择和您的责任
移民课程
我对 Git 的了解相当薄弱,因此对于 Mercurial+subrepo -> monolithic Git 我只能这样看到和描述:
Mercurial+subrepo -> 整体 Mercurial -> 整体 Git 存储库