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

问题是:这个git subrepo内部有另一个git子存储库,并且没有被 pull 出(它在git的subrepo .gitmodules文件中),除非我在git subrepo上执行了git clone --recursive:这样可以正常工作。

问题:我在另一台计算机的存储库中执行了hg pull,它 pull 出git subrepo,但没有 pull 出.gitmodules。 .gitmodules仅在我执行git clone --recursive时才 pull 入另一台计算机中。

有人对这种情况有什么建议吗?丑陋的解决方案是执行git clone并简单地将所有文件(包括git元数据)添加到我的Merurial存储库中,而不像子仓库一样。

最佳答案

我认为最好的解决办法是修补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提取路径和URL)。如果您正在处理一个变化很大的.gitmodules文件,这可能没有吸引力(每次.hgsub更改时,您必须非常勤奋地同步.gitmodules)。

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

  • gitsub —一个“叶子”存储库(没有Git子模块)
  • gitsuper —一个Git的“ super 项目”;gitsub/是gitsub作为子模块
  • hgsuper2 — Mercurial的“ super 项目”;gitsuper/是gitsuper作为子存储库,gitsuper/gitsub是gitsub作为子存储库。
  • hgsuper2-clone —一个克隆的Mercurial“ super 项目”;gitsuper/是gitsuper作为子存储库,gitsuper/gitsub是gitsub作为子存储库。

  • 我像这样构建并测试了它们:
  • 创建gitsub。添加并提交一些内容。
  • 创建gitsuper。
  • 添加一些内容。
  • git submodule add url-of-gitsub gitsub && git submodule init
  • git commit -m 'added gitsub'
  • 创建hgsuper2。
  • 添加一些内容。
  • git clone --recursive url-of-gitsuper gitsuper
  • echo 'gitsuper = [git]url-of-gitsuper' >> .hgsub
  • echo 'gitsuper/gitsub = [git]url-of-gitsub' >> .hgsub这最后两个步骤可以从gitsuper/.git/configgitsuper/.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 'updated gitsuper content (also gitsub)'
  • 在hgsuper2中,从Git储存库提取更改。
  • (cd gitsuper && git pull --recurse-submodules && git submodule update)下 pull 菜单中会更新gitsuper/gitsuper/gitsub/中的内容。
  • hg commit -m 'updated gitsuper (and its contents)'
  • pull 入hgsuper2克隆。
  • hg pull -u来自Git的内容已更新。

  • 我的测试有效(使用Mercurial 1.8.1和Git 1.7.4.1),但是我注意到一个错误。 Mercurial会创建并 checkout 一个奇怪的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存储库(基于Git的Mercurial子存储库)并使用git checkout HEAD~0 && git branch -D origin/master删除分支来解决该问题(第一个分离HEAD,(更重要的是)移出该分支,以便可以在下一个删除它命令)。只要您在Git存储库中没有任何本地更改更改,此变通办法是完全安全的。

    另一个小问题是,在Mercurial创建的Git super 存储库中发布Git子模块命令之前,您需要运行git submodule init让Git知道其子模块(这些子模块被克隆到正确的位置,但是它们是由Mercurial建立的,因此.git/config中没有任何条目。

    同样,如果您计划从基于Git的Mercurial子存储库内部创作对Git管理的内容的更改,那么在提交Mercurial之前,请务必始终添加所有Git子模块,进行提交并从Git子存储库中推送, “ super 项目”。否则,您可能会遇到这样的情况:Mercurial使用gitsuper和gitsub的一种组合,而gitsuper本身指的是gitsub的不同版本。换句话说,由于您将绕过Git的子模块代码(通过将Git子模块作为Mercurial子存储库进行管理),因此您需要注意保持Git对子模块的看法与Mercurial的观点保持同步。

    关于git - 使用在Mercurial存储库中具有另一个git subrepo的git subrepo,这可能吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5420664/

    10-13 05:23