2011-03-24 46 views
5

我有一个mercurial仓库,并没有添加任何问题git subrepo(hg 1.8)。使用在mercurial存储库中有另一个git subrepo的git subrepo,这可能吗?

问题是:这个混帐subrepo内部有它自己的其它混帐subrepository并没有被拉(它在Git的subrepo .gitmodules文件),除非我在我的git subrepo做git clone --recursive:这样做它的工作方式。

问题:我在另一台机器的存储库中做了一个hg pull,它拉动了git subrepo,但它并没有拉动.gitmodules。当我做了一个git clone --recursive时.gitmodules只在另一台机器上被拉出。

有没有人有任何建议来处理这种情况? 丑陋的解决方案是做一个git clone,并简单地将所有文件(包括git元数据)添加到我的mercurial存储库,而不像subrepo。

回答

3

我想最好的解决将是修补水银的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。

    我建造和测试他们是这样的:

    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. hg add .hgsub && hg commit -m 'added Git subrepositories'
    4. 克隆hgsuper2克隆hgsuper2
      它得到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/由拉更新。
      2. hg commit -m 'updated gitsuper (and its contents)'
    8. 拉进hgsuper2克隆
      1. 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“超级项目”。否则,可能会在那里水银使用gitsupergitsub的一个组合gitsuper本身指的是不同版本gitsub的结束与一个局面。换句话说,由于您将绕过Git的子模块代码(通过将Git子模块作为Mercurial子库进行管理),您需要小心将Git的子模块视图与Mercurial的子模块保持同步。

  • +0

    令人惊叹的答案。赏金是你的。感谢所有的努力。我要测试解决方法,并且可能会在mercurial的代码和邮件列表中进行一些关于修补此行为的搜索。 – 2011-04-03 19:19:46

    +0

    当时你的回答确实很棒,但我只是放弃了所有这些疯狂。 :) – 2015-05-14 04:57:51

    0

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

    +0

    该文件是很老。它很可能是在Git在Git 1.5.3(2007年9月)中获得子模块支持之前编写的。在Git 1.5.4(2008年2月)中弃用了它使用的“虚假命令”('git-clone'而不是'git clone'),并从Git 1.6(2008年8月)中的正常PATH中取出。 我不知道该文件应该如何帮助提问者。是否应该提供一些关于如何手动管理子项目的想法? 在我看来,这主要是一个Mercurial问题(如何让它自动在基于Git的子库中使用'.gitmodules'文件)。 – 2011-04-03 06:15:45

    +0

    @Chris Johnsen:正确。 Mercurial可以将git repos作为子库,但是当这些git仓库充当hg子仓库时,它们自己拥有一个git subrepo(在.gitmodules文件中).gitmodules中的这个仓库不会被克隆。我必须手动克隆git subrepo。 – 2011-04-03 06:18:54

    1

    适合未来的潜伏者。你可能会真正使用Hg-Git plugin为水银获得git的子模块的自动检索:

    1. 通过apt /豆子/ PIP /安装扩展...并激活它在你的~/.hgrc
    2. 导航到你的项目目录,或只是通过hg init test && cd test
    3. 克隆您的git依赖一些虚拟存储库(其中也有它自己的子模块)和指甲它到你想要的承诺:hg clone https://github.com/user/libawesome.git && (cd libawesome && hg up release)
    4. 将它保存在.hgsub任何其他汞subrepository与合作MMIT变化:echo "libawesome = https://github.com/user/libawesome.git" >> .hgsub && hg add .hgsub && hg ci -m "git subrepository added;"
    5. 现在,您可以验证git的依赖是传递性克隆:(cd .. && hg clone test test2)
    相关问题