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

发布于 2024-10-26 22:03:15 字数 608 浏览 7 评论 0原文

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

问题是:这个 git subrepo 内部有另一个 git subrepository 并且它没有被拉取(它位于 git 的 subrepo .gitmodules 文件中),除非我执行 git clone --recursive< /code> 在我的 git subrepo 上:这样做是有效的。

问题:我在另一台机器上的存储库中执行了 hg pull ,它提取了 git subrepo,但它没有提取 .gitmodules >。当我执行 git clone --recursive 时,.gitmodules 仅被拉入另一台机器。

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

I have a mercurial repository, and have added without problems a git subrepo (hg 1.8).

Problem is: this git subrepo has ANOTHER git subrepository inside itself and it isn't being pulled (it's in the git's subrepo .gitmodules file), unless I do a git clone --recursive on my git subrepo: doing this way it works.

The problem: I do a hg pull in my repository in another machine, it pulls the git subrepo, but it doesn't pull the .gitmodules. The .gitmodules was only pulled in the other machine when I did a git clone --recursive.

Does anybody has any suggestions to handle this situation? The ugly solution is to do a git clone and simply add all the files (including git metadata) to my mercurial repository, without acting like a subrepo.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

莫多说 2024-11-02 22:03:15

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


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

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

  • gitsub - 一个“leaf”存储库(无 Git 子模块)
  • gitsuper - 一个 Git“超级项目”;
    gitsub/gitsub 作为子模块
  • hgsuper2 — Mercurial“超级项目”;
    gitsuper/gitsuper 作为子存储库,
    gitsuper/gitsubgitsub 作为子存储库。
  • hgsuper2-clone — 克隆的 Mercurial“超级项目”;
    gitsuper/gitsuper 作为子存储库,
    gitsuper/gitsubgitsub 作为子存储库。

我像这样构建和测试它们:

  1. 创建gitsub。添加并提交一些内容。
  2. 创建gitsuper
    1. 添加一些内容。
    2. git 子模块 add url-of-gitsub gitsub && git 子模块初始化
    3. git commit -m '添加了 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 '添加了 Git 子存储库'
  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 '更新了 gitsuper 内容(也是 gitsub)'
  7. hgsuper2 中,从 Git 超级仓库中提取更改。
    1. (cd gitsuper && git pull --recurse-submodules && git 子模块更新)
      gitsuper/gitsuper/gitsub/ 中的内容通过拉取进行更新。
    2. hg commit -m '更新了 gitsuper(及其内容)'
  8. 拉入hgsuper2-clone
    1. hg pull -u
      Git 的内容已更新。

我的测试有效(使用 Mercurial 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 存储库(基于 Git 的 Mercurial 子存​​储库)并使用 git checkout HEAD 删除分支来解决这个问题~ 0 && gitbranch -D origin/master (第一个分离 HEAD 并且(更重要的是)移出分支,以便下一个命令可以将其删除)。只要您在 Git 存储库中没有任何本地更改,此解决方法就是完全安全的。

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

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

I suppose the best fix would be to patch Mercurial’s Git subrepository support to always use Git’s recursive options (e.g. git clone --recursive when cloning a Git-based subrepository, git pull --recurse-submodules && git submodule update after pulling an updated Git-based subrepository, etc.). I know that the Git developers specifically chose to not automatically initialize submodules because one of the workflows they want to support is “I never want to see any of the the submodules”, but maybe “always initialize all subrepositories” is a better match to the default Mercurial mode of operation (I am not much of a Mercurial user, so I do not have a good idea of what the default Mercurial style would be).


Until that happens, you might be able to work around the problem by translating the subrepo/.gitmodules entries into .hgsub entries. It is easy to do manually, but you could probably automate it if it was important (use git config to extract the paths and URLs from .git/config and/or .gitmodules). This may be unappealing if you are dealing with a .gitmodules file that changes much (you would have to be very diligent about synchronizing .hgsub each time .gitmodules changed).

I tested this with four repositories:

  • gitsub — a “leaf” repository (no Git submodules)
  • gitsuper — a Git “superproject”;
    gitsub/ is gitsub as a submodule
  • hgsuper2 — a Mercurial “superproject”;
    gitsuper/ is gitsuper as a subrepository,
    gitsuper/gitsub is gitsub as a subrepository.
  • hgsuper2-clone — a cloned Mercurial “superproject”;
    gitsuper/ is gitsuper as a subrepository,
    gitsuper/gitsub is gitsub as a subrepository.

I built and tested them like this:

  1. Create gitsub. Add and commit some content.
  2. Create gitsuper.
    1. Add some content.
    2. git submodule add url-of-gitsub gitsub && git submodule init
    3. git commit -m 'added gitsub'
  3. Create hgsuper2.
    1. Add some content.
    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
      These last two steps could be automated from bits of gitsuper/.git/config and gitsuper/.gitmodules.
    5. hg add .hgsub && hg commit -m 'added Git subrepositories'
  4. Clone hgsuper2-clone from hgsuper2.
    It gets the appropriate contents in gitsuper/ and gitsuper/gitsub/.
  5. Update and commit new content to gitsub.
  6. Update gitsuper.
    1. Add or change some content and stage it.
    2. (cd gitsub && git pull origin master)
    3. git add gitsub && git commit -m 'updated gitsuper content (also gitsub)'
  7. In hgsuper2, pull changes from Git suprepositories.
    1. (cd gitsuper && git pull --recurse-submodules && git submodule update)
      The content in gitsuper/ and gitsuper/gitsub/ is updated by the pull.
    2. hg commit -m 'updated gitsuper (and its contents)'
  8. Pull into hgsuper2-clone.
    1. hg pull -u
      The content from Git has been updated.

My tests worked (using Mercurial 1.8.1 and Git 1.7.4.1), but I noticed one bug. Mercurial creates and checks out an oddly named Git branch (origin/master (i.e. refs/heads/origin/master) instead of using a detached HEAD (like Git does with its submodules) or just using master (i.e. refs/heads/master)). It also seems to get a bit wedged at times, resulting in errors like this:

fatal: git checkout: branch origin/master already exists
abort: git checkout error 128 in gitsuper

I worked around the problem by going into the Git repository in question (the Git-based Mercurial subrepository) and deleting the branch with git checkout HEAD~0 && git branch -D origin/master (the first detaches HEAD and (more importantly) moves off of the branch so it can be deleted by the next command). This workaround is completely safe as long as you do not have any local changes changes in the Git repository.

Another small problem is that you will need to run git submodule init to let Git know about its submodules before issuing Git submodule commands in a Git super repository that was created by Mercurial (the submodules were cloned to the right places, but they were established by Mercurial, so there are no entries for them in .git/config).

Similarly, if you plan on authoring changes to the content that is managed by Git from inside the Git-based Mercurial subrepository, then you should be careful to always add any Git submodules, commit, and push from the Git subrepositories before committing in the Mercurial “superproject”. Otherwise, you might end up with a situation where Mercurial uses one combination of gitsuper and gitsub while gitsuper itself refers to a different version of gitsub. In other words, since you will be bypassing Git’s submodule code (by managing the Git submodules as Mercurial subrepositories), you will need to be careful to keep Git’s view of the submodules synchronized with that of Mercurial.

国产ˉ祖宗 2024-11-02 22:03:15

对于未来的潜伏者。您实际上可能会使用 Mercurial 的 Hg-Git 插件 来自动检索 git 子模块:

  1. 安装扩展通过 apt/pacman/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 中,作为任何其他 hg 子存储库 并提交更改:echo "libawesome = https://github.com/user/libawesome.git">> .hgsub && hg 添加 .hgsub && hg ci -m "git subrepository added;"
  5. 您现在可以验证 git 依赖项是否已传递克隆:(cd .. && hg clone test test2)

For future lurkers. You might actually use Hg-Git plugin for Mercurial to get automatic retrieval of git submodules:

  1. Install the extension via apt/pacman/pip/... and activate it in your ~/.hgrc
  2. Navigate to your project directory or just some dummy repository via hg init test && cd test
  3. Clone your git dependency (which also has it's own submodules) and nail it to the commit you want: hg clone https://github.com/user/libawesome.git && (cd libawesome && hg up release)
  4. Save it in .hgsub as any other hg subrepository and commit changes: echo "libawesome = https://github.com/user/libawesome.git" >> .hgsub && hg add .hgsub && hg ci -m "git subrepository added;"
  5. You can now verify that git dependencies are transitively cloned: (cd .. && hg clone test test2)
夜未央樱花落 2024-11-02 22:03:15

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

Git doesn't really "like" subprojects. I did a little looking around, and it seems like http://git.rsbx.net/Notes/Git_Subprojects.txt might contain the information you're looking for?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文