使用在mercurial存储库中有另一个git subrepo的git subrepo,这可能吗?

时间:2011-03-24 14:25:39

标签: git version-control mercurial subrepos

我有一个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存储库中,而不像子服务器那样。

3 个答案:

答案 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 - 一个“叶子”存储库(没有Git子模块)
  • gitsuper - 一个Git“超级项目”;
    gitsub/ gitsub 作为子模块
  • hgsuper2 - 一个Mercurial“超级项目”;
    gitsuper/ gitsuper 作为子库,
    gitsuper/gitsub gitsub 作为子库。
  • hgsuper2-clone - 一个克隆的Mercurial“超级项目”;

    gitsuper/ gitsuper 作为子库,
    gitsuper/gitsub gitsub 作为子库。

我建造并测试了它们:

  1. 创建 gitsub 。添加并提交一些内容。
  2. 创建 gitsuper
    1. 添加一些内容。
    2. git submodule add url-of-gitsub gitsub && git submodule init
    3. git commit -m 'added gitsub'
  3. 创建 hgsuper2
    1. 添加一些内容。
    2. git clone --recursive url-of-gitsuper gitsuper
    3. echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
    4. echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub
      最后两个步骤可以通过gitsuper/.git/configgitsuper/.gitmodules
    5. 的位自动完成
    6. hg add .hgsub && hg commit -m 'added Git subrepositories'
  4. hgsuper2 克隆 hgsuper2-clone
    它会在gitsuper/gitsuper/gitsub/中获得相应的内容。
  5. 更新新内容并将其提交至 gitsub
  6. 更新 gitsuper
    1. 添加或更改部分内容并暂存。
    2. (cd gitsub && git pull origin master)
    3. git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
  7. hgsuper2 中,从Git suprepositories中提取更改。
    1. (cd gitsuper && git pull --recurse-submodules && git submodule update)
      gitsuper/gitsuper/gitsub/中的内容由pull更新。
    2. hg commit -m 'updated gitsuper (and its contents)'
  8. 进入 hgsuper2-clone
    1. hg pull -u
      来自Git的内容已经更新。
  9. 我的测试工作(使用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子模块:

  1. 通过apt / pacman / pip / ...安装扩展程序并在~/.hgrc
  2. 中激活它
  3. 通过hg init test && cd test
  4. 导航到您的项目目录或只是一些虚拟存储库
  5. 克隆你的git依赖项(也有它自己的子模块)并将其钉在你想要的提交上:hg clone https://github.com/user/libawesome.git && (cd libawesome && hg up release)
  6. 将其保存在.hgsub中作为任何其他 hg子存储库并提交更改:echo "libawesome = https://github.com/user/libawesome.git" >> .hgsub && hg add .hgsub && hg ci -m "git subrepository added;"
  7. 您现在可以验证是否可以传递克隆git依赖项:(cd .. && hg clone test test2)

答案 2 :(得分:0)

Git并不真正“喜欢”子项目。我做了一点环顾四周,似乎http://git.rsbx.net/Notes/Git_Subprojects.txt可能包含您正在寻找的信息?