将git worktree与git子模块一起使用时会出现什么问题

时间:2015-08-07 07:25:05

标签: git git-submodules git-worktree

我最近发现了git worktree命令:

  

新工作目录链接到当前存储库,共享除工作目录特定文件(如HEAD,索引等)之外的所有内容。

但文档也表明

  

......对子模块的支持不完整。建议不要对超级项目进行多次检出。

没有进一步解释出现了什么问题。

有人可以告诉我有关期待的问题吗?例如,如果我使用以这种方式生成的单独工作树仅用于不影响子模块的更改,我会没事吗?

1 个答案:

答案 0 :(得分:18)

Commit a83a66a非常清楚:

  

git-submodule.sh期望$GIT_DIR/config为每个工作树,至少对submodule.* part而言。   在这里,我认为我们有两个选择:

     
      
  • 更新config.c也可以阅读   除了$GIT_DIR/config.worktree(每个工作树)   $GIT_DIR/config(共享)并在新版本中存储特定于工作树的变量   地方,
  •   
  • 或更新git-submodule.sh直接读/写submodule.*   来自$GIT_DIR/config.submodule(每个工作树)。
  •   
     

这需要时间来妥善解决。同时,请注意   用户不应在子模块上下文中使用多个工作树。

更一般地说,放置那些子模块的位置?

  

有几种选择:

     
      
  • 您可能希望将$SUB repos保留在其他位置(可能位于中央位置)   在$SUPER之外。嵌套子模块也是如此   超级项目可能是另一个超级项目的子模块。
  •   
  • 您可能希望将所有$SUB个回购邮件保留在$SUPER/modules(或某些   $SUPER
  • 中的其他地方   
  • 我们甚至可以进一步推送它并将所有$SUB个回购合并到$SUPER   而不是分开存储它们。但这至少需要   ref namespace已启用。
  •   

此提交是对commit df56607的回答。

从git用户的角度来看,这意味着git submodule update --init --recursive并不完全知道 where 来检查子模块。
它们是否在所有工作区中重复,或者它们是否集中在某处?目前还没有正式指定。

一年后(使用git 2.9),clacke添加了in the comments

  

混乱已经解决,但不是以最佳方式解决   子模块现在可以正常工作,但是每个工作树都有自己的一组子模块存储库(在motherrepo.git/worktree/<worktreename>/modules/<submodule>下),所以如果你有一个很大的子模块,你正面临一些严重的磁盘使用。

Git别名来处理子树中的子模块

别名git wtas期望git wta是全局定义的,或者至少是所有涉及的回购定义。不包括保修。如果您的路径名称中有空格,您最喜欢的宠物可能会感染疼痛。

它希望你的repo中的一个结构就像启动了子模块的非裸仓库中的结构一样,所以如果你有一个裸仓库,你就必须模仿那个设置。具有名称(非路径)foo的子模块位于<your-.git-directory>/modules/foo(不是.../foo.git)。如果repo中没有某个模块,它就不会崩溃,只是跳过它。

还有改进的余地。它不处理子模块中的子模块,它只降低一级。 可以只是将子模块git wta调用更改为git wtas来电,但我还没有对此进行验证。

- clacke

另见git worktree move(Git 2.17 +,2018年第二季度)。

实际上,在Git 2.21(2019年第一季度)之前,&#34; git worktree remove&#34;和&#34; git worktree move&#34;当涉及子模块时拒绝工作 已放宽此选项以忽略未初始化的子模块

commit 00a6d4dNguyễn Thái Ngọc Duy (pclouds)(2019年1月5日) (由Junio C Hamano -- gitster --合并于commit 726f89c,2019年1月18日)

  

worktree:允许(重新)移动未初始化子模块的工作树

     

未初始化的子模块没有什么值得我们担心的。它们只是SHA-1   让&#34; worktree remove&#34;和&#34; worktree move&#34;继续在这种情况下,以便人们仍然可以在repos上使用多个工作树,其中包含从未填充的可选子模块,例如在sha1collisiondetection脚本签出时git.git doc-diff

     

请注意,对于&#34; worktree remove&#34;,用户可能初始化子模块(*),进行一些提交(但不推送),然后取消初始化。
  此时,子模块未填充,但宝贵的新提交仍在:

$GIT_COMMON_DIR/worktrees/<worktree>/modules/<submodule>
     

目录,我们不应该允许删除工作树或我们永远丢失这些提交   添加新目录检查是为了防止这种情况。

     

*)是的,无论如何他们都是这样做的,因为&#34; git submodule&#34;    会在submodule.*中添加$GIT_COMMON_DIR/config,这是在多个工作树中共享的   但这并不意味着我们会让他们更加紧张。