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

Som*_*DOS 5 git version-control mercurial subrepos

我有一个mercurial存储库,并添加了没有问题的git subrepo(hg 1.8).

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

问题是:我hg pull在另一台机器的存储库中执行了一次,它会拉动它git subrepo,但它不会拉动它.gitmodules.当我做了一个.gitmodules只被拉到另一台机器上git clone --recursive.

有没有人有任何建议来处理这种情况?该丑陋的解决办法是做一个git clone和简单的所有文件(包括git的元数据)添加到我的Mercurial库,不像个subrepo.

Chr*_*sen 3

我想最好的解决办法是修补 Mercurial\xe2\x80\x99s Git 子存储库支持,以始终使用 Git\xe2\x80\x99s 递归选项(例如,git clone --recursive在克隆基于 Git 的子存储库时,git pull --recurse-submodules && git submodule update在拉取更新的基于 Git 的子存储库后, ETC。)。我知道 Git 开发人员特别选择不自动初始化子模块,因为他们想要支持的工作流程之一是 \xe2\x80\x9c 我永远不想看到任何子模块 \xe2\x80\x9d,但也许 \xe2\ x80\x9calways 初始化所有子存储库\xe2\x80\x9d 更适合默认的 Mercurial 操作模式(我不是 Mercurial 用户,所以我不太清楚默认的 Mercurial 样式是什么) 。

\n\n
\n\n

在此之前,您也许可以通过将subrepo/.gitmodules条目转换为.hgsub条目来解决该问题。手动执行很容易,但如果重要的话您可以将其自动化(用于从and/orgit config中提取路径和 URL )。如果您正在处理变化很大的文件,这可能没有吸引力(您必须非常勤奋地同步每次变化)。.git/config.gitmodules.gitmodules.hgsub.gitmodules

\n\n

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

\n\n
    \n
  • gitsub \xe2\x80\x94 a \xe2\x80\x9cleaf\xe2\x80\x9d 存储库(无 Git 子模块)
  • \n
  • gitsuper \xe2\x80\x94 a Git \xe2\x80\x9csuperproject\xe2\x80\x9d;
    \ngitsub/gitsub作为子模块
  • \n
  • hgsuper2 \xe2\x80\x94 一个 Mercurial \xe2\x80\x9csuperproject\xe2\x80\x9d;
    \ngitsuper/gitsuper作为子存储库,
    \ngitsuper/gitsubgitsub作为子存储库。
  • \n
  • hgsuper2-clone \xe2\x80\x94 克隆的 Mercurial \xe2\x80\x9csuperproject\xe2\x80\x9d;
    \ngitsuper/gitsuper作为子存储库,
    \ngitsuper/gitsubgitsub作为子存储库。
  • \n
\n\n

我像这样构建并测试了它们:

\n\n
    \n
  1. 创建gitsub . 添加并提交一些内容。
  2. \n
  3. 创建gitsuper。\n
      \n
    1. 添加一些内容。
    2. \n
    3. git submodule add url-of-gitsub gitsub && git submodule init
    4. \n
    5. git commit -m 'added gitsub'
    6. \n
  4. \n
  5. 创建hgsuper2。\n
      \n
    1. 添加一些内容。
    2. \n
    3. git clone --recursive url-of-gitsuper gitsuper
    4. \n
    5. echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
    6. \n
    7. echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub
      gitsuper/.git/config\n最后两个步骤可以通过和的位实现自动化gitsuper/.gitmodules
    8. \n
    9. hg add .hgsub && hg commit -m 'added Git subrepositories'
    10. \n
  6. \n
  7. hgsuper2克隆hgsuper2-clone。\n它获取和中的适当内容。
    gitsuper/gitsuper/gitsub/
  8. \n
  9. 更新新内容并将其提交到gitsub
  10. \n
  11. 更新gitsuper。\n
      \n
    1. 添加或更改一些内容并暂存。
    2. \n
    3. (cd gitsub && git pull origin master)
    4. \n
    5. git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
    6. \n
  12. \n
  13. hgsuper2中,从 Git 存储库中提取更改。\n
      \n
    1. (cd gitsuper && git pull --recurse-submodules && git submodule update)
      \ngitsuper/和中的内容gitsuper/gitsub/是通过拉取来更新的。
    2. \n
    3. hg commit -m 'updated gitsuper (and its contents)'
    4. \n
  14. \n
  15. 拉入hgsuper2-clone。\n
      \n
    1. hg pull -u
      \nGit 的内容已更新。
    2. \n
  16. \n
\n\n

我的测试有效(使用 Mercurial 1.8.1 和 Git 1.7.4.1),但我注意到一个错误。Mercurial 创建并签出一个名称奇怪的 Git 分支(origin/master(ie refs/heads/origin/master),而不是使用分离的 HEAD(就像 Git 对其子模块所做的那样)或仅使用master(ie refs/heads/master))。有时它似乎也有点卡住,导致如下错误:

\n\n
fatal: git checkout: branch origin/master already exists\nabort: git checkout error 128 in gitsuper\n
Run Code Online (Sandbox Code Playgroud)\n\n

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

\n\n

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

\n\n

同样,如果您计划从基于 Git 的 Mercurial 子存​​储库内部对 Git 管理的内容进行创作更改,那么您应该小心,在在 Mercurial 中提交之前,始终从 Git 子存储库添加任何 Git 子模块、提交和推送。 \xe2\x80\x9csuperproject\xe2\x80\x9d。否则,您可能最终会遇到 Mercurial 使用gitsupergitsub的组合,而gitsuper本身引用不同版本的gitsub的情况。换句话说,由于您将绕过 Git\xe2\x80\x99s 子模块代码(通过将 Git 子模块作为 Mercurial 子存​​储库进行管理),因此您需要小心保持子模块的 Git\xe2\x80\x99s 视图与是 Mercurial 的。

\n