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

Joa*_*ner 31 git git-submodules git-worktree

我最近发现了这个git worktree命令:

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

但是文档也表明了这一点

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

没有进一步解释什么是错误的.

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

Von*_*onC 19

提交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其他地方(可能在中心位置)保留回购$SUPER.对于嵌套子模块也是如此,其中超级项目可能是另一个超级项目的子模块.
  • 您可能希望保留所有$SUB回购$SUPER/modules(或其他地方$SUPER)
  • 我们甚至可以进一步推动它并将所有$SUB回购合并到$SUPER 而不是单独存储它们.但这至少需要启用ref命名空间.

这个提交是提交df56607的答案.


从一个git的用户点,这意味着一个git submodule update --init --recursive不知道到底哪里签子模块.
它们是否在所有工作区中重复,或者它们是否集中在某处?这尚未正式指定.


一年后(并使用git 2.9),clacke 在评论中补充道

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


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

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

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

还有改进的余地.它不处理子模块中的子模块,它只降低一级.它可能只是将子模块git wta调用更改为一个git wtas调用,但我还没有验证这一点.

- 克拉克


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


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

提交00a6d4d通过(2019年1月5日)阮泰玉维战(pclouds).
(由Junio C gitsterHamano合并- -提交726f89c,2019年1月18日)

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

未初始化的子模块没有什么值得我们担心的.它们只是SHA-1.在这种情况下,
让" worktree remove"和" worktree move"继续,以便人们仍然可以在repos上使用多个工作树,并且可以使用从未填充的可选子模块,例如sha1collisiondetectiongit.git通过doc-diff脚本检出时.

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

$GIT_COMMON_DIR/worktrees/<worktree>/modules/<submodule>
Run Code Online (Sandbox Code Playgroud)

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

(*)是的,他们是由因为"这样做有点犯糊涂git submodule"将加submodule.*$GIT_COMMON_DIR/config,其在多个worktrees共享.
但这并不意味着我们会让他们更加紧张.

  • 感谢您的研究!但是我仍然不确定什么实际上会中断,以及什么动作会起作用。你能试着从 git 用户的角度来描述吗? (3认同)
  • 截至今天,我提出这个问题是因为混乱已经解决,但不是以最佳方式解决。据我所知,子模块现在工作正常,但每个工作树都有自己的一组子模块存储库(在`motherrepo.git/worktree/&lt;worktreename&gt;/modules/&lt;submodule&gt;`下),所以如果你有一个很大的子模块,您正面临一些严重的磁盘使用情况。 (2认同)
  • 据我了解,唯一的问题是子存储库的“管理文件”(HEAD 等)对于不同的工作目录可能有所不同,因为它们(工作目录)可能具有不同的关联子存储库提交。但是为什么我们不能以与工作目录本身完全相同的方式解决这个问题,即将子存储库的“内容”存储在`$GIT_COMMON_DIR/modules/&lt;submodule&gt;`中,并将管理文件存储在`$GIT_COMMON_DIR中/worktrees/&lt;工作树&gt;/modules/&lt;子模块&gt;`? 这样,工作目录将是独立的,而不会重复其子模块的对象。 (2认同)