我想最好的解决将是修补水银的Git的subrepository支持始终使用Git的递归选项(例如git clone --recursive
拉动更新的Git和subrepository等之后克隆一个Git和subrepository,git pull --recurse-submodules && git submodule update
时)。我知道Git开发人员特别选择不自动初始化子模块,因为他们希望支持的工作流之一是“我从不想看到任何子模块”,但也许“始终初始化所有子模块”是更好的匹配默认Mercurial操作模式(我没有太多的Mercurial用户,所以我对默认的Mercurial风格会有什么不了解)。
等到那个时候,你也许可以通过翻译subrepo/.gitmodules
项为.hgsub
项解决此问题。手动操作很容易,但如果重要的话,您可能会自动执行该操作(使用git config
从.git/config
和/或.gitmodules
中提取路径和URL)。如果你正在处理的.gitmodules
文件变化很大(每次更改.gitmodules
时你都必须非常勤奋地同步.hgsub
),这可能没有吸引力。
我有四个存储库进行测试的: - 一个“叶”储存库(没有GIT中的子模块)
gitsuper -
- gitsub一个GIT中“上层项目”;
gitsub/
是gitsub作为子模块
- hgsuper2 - 一个水银“上层项目”;
gitsuper/
是gitsuper作为subrepository,
gitsuper/gitsub
是gitsub作为subrepository。
- hgsuper2-clone - 克隆的Mercurial“superproject”;
gitsuper/
是gitsuper作为subrepository,
gitsuper/gitsub
是gitsub作为subrepository。
我建造和测试他们是这样的:
- 创建gitsub。添加并提交一些内容。
- 创建gitsuper。
- 添加一些内容。
git submodule add url-of-gitsub gitsub && git submodule init
git commit -m 'added gitsub'
- 创建hgsuper2。
- 添加一些内容。
git clone --recursive url-of-gitsuper gitsuper
echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub
最后两个步骤可以从gitsuper/.git/config
和gitsuper/.gitmodules
位被自动化。
hg add .hgsub && hg commit -m 'added Git subrepositories'
- 克隆hgsuper2克隆从hgsuper2。
它得到gitsuper/
和gitsuper/gitsub/
中的适当内容。
- 更新并提交新内容至gitsub。
- 更新gitsuper。
- 添加或更改内容并将其放置。
(cd gitsub && git pull origin master)
git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
- 在hgsuper2,拉从Git的suprepositories变化。
(cd gitsuper && git pull --recurse-submodules && git submodule update)
内容在gitsuper/
和gitsuper/gitsub/
由拉更新。
hg commit -m 'updated gitsuper (and its contents)'
- 拉进hgsuper2克隆。
hg pull -u
Git的内容已更新。
我的测试工作(使用水银1.8.1和Git 1.7.4.1),但我注意到一个错误。 Mercurial创建并检出一个奇怪的Git分支(origin/master
(即refs/heads/origin/master
),而不是使用分离的HEAD(像Git对子模块做的那样)或仅使用master
(即refs/heads/master
))。它也似乎变得有点有时楔入,导致这样的错误:
fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper
我工作围绕这一问题通过进入有问题(基于Git的,水银subrepository)的Git仓库,并删除分支git checkout HEAD~0 && git branch -D origin/master
(第一个分离HEAD和(更重要的是)离开分支,所以它可以被下一个命令删除)。只要您在Git存储库中没有任何本地更改,此解决方法就完全安全。
另一个小问题是,你将需要运行git submodule init
让Git的知道它的子模块,是由水银创建(子模块克隆到正确的地方一个Git超级仓库发出的Git子模块命令之前,但他们由Mercurial建立,因此.git/config
中没有他们的条目)。同样,如果您计划从基于Git的Mercurial子库中创建对由Git管理的内容的更改,那么您应该小心始终在Git子库之前添加任何Git子模块,提交和推送承诺参与Mercurial“超级项目”。否则,可能会在那里水银使用gitsuper和gitsub的一个组合而gitsuper本身指的是不同版本gitsub的结束与一个局面。换句话说,由于您将绕过Git的子模块代码(通过将Git子模块作为Mercurial子库进行管理),您需要小心将Git的子模块视图与Mercurial的子模块保持同步。
令人惊叹的答案。赏金是你的。感谢所有的努力。我要测试解决方法,并且可能会在mercurial的代码和邮件列表中进行一些关于修补此行为的搜索。 – 2011-04-03 19:19:46
当时你的回答确实很棒,但我只是放弃了所有这些疯狂。 :) – 2015-05-14 04:57:51