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

使用在mercurial存储库中有另一个git子回购的git子回购,这可能吗?,git,version-control,mercurial,subrepos,Git,Version Control,Mercurial,Subrepos,我有一个mercurial存储库,并且毫无问题地添加了一个git subrepo() 问题是:这个git subrepo在其内部有另一个git子存储库,并且它不会被拉取(它在git的subrepo.gitmodules文件中),除非我在我的git subrepo上做了一个git克隆--recursive:这样做是可行的 问题是:我在另一台机器的存储库中执行了一个hg pull,它拉取了git subrepo,但没有拉取.gitmodules。.gitmodules只有在我执行git克隆--rec

我有一个mercurial存储库,并且毫无问题地添加了一个git subrepo()

问题是:这个git subrepo在其内部有另一个git子存储库,并且它不会被拉取(它在git的subrepo
.gitmodules
文件中),除非我在我的git subrepo上做了一个
git克隆--recursive
:这样做是可行的

问题是:我在另一台机器的存储库中执行了一个
hg pull
,它拉取了
git subrepo
,但没有拉取
.gitmodules
。.gitmodules只有在我执行
git克隆--recursive
时才被拉入另一台机器


有人对处理这种情况有什么建议吗?丑陋的解决方案是做一个
git克隆
,简单地将所有文件(包括git元数据)添加到我的mercurial存储库中,而不是像子repo一样。我四处看了看,它似乎可能包含了您要查找的信息?

我想最好的修复方法是修补Mercurial的Git子存储库支持,以便始终使用Git的递归选项(例如,
git clone——递归
克隆基于git的子存储库时,
git pull——在提取更新的基于git的子存储库后递归子模块和&git子模块更新
,等等)。我知道Git开发人员特别选择不自动初始化子模块,因为他们想要支持的工作流之一是“我永远不想看到任何子模块”,但也许“总是初始化所有子存储库”更适合默认的Mercurial操作模式(我不是一个Mercurial用户,所以我不知道默认的Mercurial风格是什么)


在此之前,您可能可以通过将
subrepo/.gitmodules
条目转换为
.hgsub
条目来解决此问题。手动操作很容易,但如果重要的话,您可能可以将其自动化(使用
git-config
.git/config
和/或
.gitmodules
)提取路径和URL。如果您处理的
.gitmodules
文件变化很大(每次
.gitmodules
发生变化时,您必须非常认真地同步
.hgsub

我用四个存储库对此进行了测试:

  • gitsub-一个“叶”存储库(没有Git子模块)
  • gitsuper-Git“超级项目”;
    gitsub/
    是否将gitsub作为子模块
  • hgsuper2——一个反复无常的“超级项目”;
    gitsuper/
    是否将gitsuper作为子存储库,
    gitsuper/gitsub
    将gitsub作为子存储库
  • hgsuper2克隆-克隆的Mercurial“超级项目”;
    gitsuper/
    是否将gitsuper作为子存储库,
    gitsuper/gitsub
    将gitsub作为子存储库
我像这样构建和测试它们:

fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper
  • 创建gitsub。添加并提交一些内容
  • 创建gitsuper。
  • 添加一些内容
  • git子模块添加gitsub和git子模块init的url
  • git提交-m'添加了gitsub'
  • 创建hgsuper2。
  • 添加一些内容
  • git克隆——gitsuper的递归url gitsuper
  • echo'gitsuper=[git]gitsuper的url'>>.hgsub
  • echo'gitsuper/gitsub=[git]gitsub的url'>.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'更新的gitsuper内容(也是gitsub)
  • 在hgsuper2中,从Git Superpositories中提取更改。
  • (cd gitsuper和&git pull——递归子模块和&git子模块更新)

    通过pull更新
    gitsuper/
    gitsuper/gitsub/
    中的内容
  • hg commit-m'更新的gitsuper(及其内容)
  • 进入hgsuper2克隆。
  • hg pull-u

    Git中的内容已更新
  • 我的测试成功了(使用Mercurial 1.8.1和Git 1.7.4.1),但我注意到了一个bug。Mercurial创建并检查了一个命名奇怪的Git分支(
    origin/master
    (即
    refs/heads/origin/master
    ),而不是使用分离的头(就像Git对其子模块所做的那样)或只使用
    master
    (即
    refs/heads/master
    )。有时它似乎也会有点被楔入,导致如下错误:

    fatal: git checkout: branch origin/master already exists
    abort: git checkout error 128 in gitsuper
    
    我通过进入所讨论的Git存储库(基于Git的Mercurial子存储库)并使用
    Git checkout HEAD~0和&Git branch-D origin/master
    (第一个分离HEAD并(更重要的是)移出分支,以便可以通过下一个命令将其删除)来解决这个问题。只要您在Git存储库中没有任何本地更改,此解决方案是完全安全的

    另一个小问题是,在Mercurial创建的git超级存储库中发出git子模块命令之前,需要运行
    git submodule init
    ,让git了解其子模块(子模块被克隆到正确的位置,但它们是由Mercurial建立的,因此在
    .git/config
    中没有它们的条目)

    类似地,如果您计划对Git从insi管理的内容进行修改