我有一个mercurial存储库,并添加了一个git subrepo(hg 1.8)没有问题。
问题是:这个git subrepo本身有另一个git子存储库而且它没有被拉(它在git的subrepo .gitmodules
文件中),除非我在我的git subrepo上做git clone --recursive
:这样做是有效的。
问题:我在另一台计算机的存储库中执行hg pull
,它会提取git subrepo
,但它不会提取.gitmodules
。当我执行git clone --recursive
时,.gitmodules只在另一台机器中被拉出。
有人有任何建议来处理这种情况吗? 丑陋的解决方案是执行git clone
并简单地将所有文件(包括git元数据)添加到我的mercurial存储库中,而不像子服务器那样。
答案 0 :(得分:3)
我认为最好的解决方法是修补Mercurial的Git子存储库支持,以便在拉出基于Git的更新子库后,在克隆基于Git的子存储库git clone --recursive
时始终使用Git的递归选项(例如git pull --recurse-submodules && git submodule update
等)。我知道Git开发人员特别选择不自动初始化子模块,因为他们想要支持的工作流之一是“我从不想看到任何子模块”,但可能“总是初始化所有子存储库”是更好的匹配默认的Mercurial操作模式(我不是Mercurial用户,所以我不太了解默认的Mercurial风格)。
在此之前,您可以通过将subrepo/.gitmodules
条目转换为.hgsub
条目来解决此问题。手动操作很容易,但如果重要的话,您可以将其自动化(使用git config
从.git/config
和/或.gitmodules
中提取路径和网址。如果您处理的.gitmodules
文件发生了很大变化,那么这可能会毫无吸引力(每次.hgsub
更改时,您都必须非常努力地同步.gitmodules
。
我用四个存储库测试了这个:
gitsub/
是 gitsub 作为子模块gitsuper/
是 gitsuper 作为子库,gitsuper/gitsub
是 gitsub 作为子库。gitsuper/
是 gitsuper 作为子库,gitsuper/gitsub
是 gitsub 作为子库。我建造并测试了它们:
git submodule add url-of-gitsub gitsub && git submodule init
git commit -m 'added gitsub'
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'
gitsuper/
和gitsuper/gitsub/
中获得相应的内容。(cd gitsub && git pull origin master)
git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
(cd gitsuper && git pull --recurse-submodules && git submodule update)
gitsuper/
和gitsuper/gitsub/
中的内容由pull更新。hg commit -m 'updated gitsuper (and its contents)'
hg pull -u
我的测试工作(使用Mercurial 1.8.1和Git 1.7.4.1),但我发现了一个错误。 Mercurial创建并检出一个奇怪命名的Git分支(origin/master
(即refs/heads/origin/master
),而不是使用分离的HEAD(就像Git对其子模块一样)或仅使用master
(即{{ 1}}))。它似乎有时会有点楔形,导致这样的错误:
refs/heads/master
我通过进入有问题的Git存储库(基于Git的Mercurial子存储库)并使用fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper
删除分支来解决问题(第一个分离HEAD和(更重要的是)离开分支,所以它可以被下一个命令删除)。只要您在Git存储库中没有任何本地更改更改,此解决方法就是完全安全的。
另一个小问题是你需要运行git checkout HEAD~0 && git branch -D origin/master
让Git知道它的子模块,然后在Mercurial创建的Git超级存储库中发出Git子模块命令(子模块被克隆到正确的位置,但它们是由Mercurial建立的,因此git submodule init
)中没有条目。
同样,如果您计划在基于Git的Mercurial子存储库中创建由Git管理的内容的更改,那么在提交之前应始终小心地从Git子存储库添加任何Git子模块,提交和推送在Mercurial“超级项目”中。否则,您最终会遇到Mercurial使用 gitsuper 和 gitsub 的一种组合的情况,而 gitsuper 本身则指的是 gitsub 。换句话说,由于您将绕过Git的子模块代码(通过将Git子模块作为Mercurial子存储库进行管理),您需要小心保持Git的子模块视图与Mercurial的子模块同步。
答案 1 :(得分:2)
未来的潜伏者。您实际上可以使用Hg-Git plugin来获取Mercurial以自动检索git子模块:
~/.hgrc
hg init test && cd test
hg clone https://github.com/user/libawesome.git && (cd libawesome && hg up release)
.hgsub
中作为任何其他 hg子存储库并提交更改:echo "libawesome = https://github.com/user/libawesome.git" >> .hgsub && hg add .hgsub && hg ci -m "git subrepository added;"
(cd .. && hg clone test test2)
答案 2 :(得分:0)
Git并不真正“喜欢”子项目。我做了一点环顾四周,似乎http://git.rsbx.net/Notes/Git_Subprojects.txt可能包含您正在寻找的信息?