gpt4 book ai didi

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

转载 作者:IT王子 更新时间:2023-10-29 01:01:51 28 4
gpt4 key购买 nike

我最近发现了 git worktree命令:

The new working directory is linked to the current repository, sharing everything except working directory specific files such as HEAD, index, etc.

但是文档也指出了

… the support for submodules is incomplete. It is NOT recommended to make multiple checkouts of a superproject.

没有进一步解释哪里出了问题。

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

最佳答案

Commit a83a66a对此很清楚:

git-submodule.sh expects $GIT_DIR/config to be per-worktree, at least for the submodule.* part.
Here I think we have two options:

  • either update config.c to also read $GIT_DIR/config.worktree (which is per worktree) in addition to $GIT_DIR/config (shared) and store worktree-specific vars in the new place,
  • or update git-submodule.sh to read/write submodule.* directly from $GIT_DIR/config.submodule (per worktree).

These take time to address properly. Meanwhile, make a note to the user that they should not use multiple worktrees in submodule context.

更一般地说,将这些子模块放在哪里?

There are a couple options:

  • You may want to keep $SUB repos elsewhere (perhaps in a central place) outside $SUPER. This is also true for nested submodules where a superproject may be a submodule of another superproject.
  • You may want to keep all $SUB repos in $SUPER/modules (or some other place in $SUPER)
  • We could even push it further and merge all $SUB repos into $SUPER instead of storing them separately. But that would at least require ref namespace enabled.

此提交是对 commit df56607 的回答.


从 git 用户的角度来看,这意味着 git submodule update --init --recursive不确切地知道在哪里检查子模块。
它们是在所有工作树中复制,还是集中在某个地方?这尚未正式指定。


一年后(以及 git 2.9),clacke添加 in the comments

the confusion has been resolved, but not in an optimal manner.
Submodules work fine now as far as I can see, but each worktree has its own set of submodule repos (under motherrepo.git/worktree/<worktreename>/modules/<submodule>), so if you have a submodule that's big, you are facing some serious disk usage.


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

别名git wtas期望 git wta是全局定义的,或者至少是针对所有涉及的 repo 协议(protocol)。不包括保修。如果您的路径名称中有空格,您最喜欢的宠物可能会感染痛苦的病毒。

它希望您的存储库中的结构类似于带有子模块的非裸存储库中的结构,因此如果您有一个裸存储库,则必须模仿该设置。具有名称(不是路径)foo 的子模块进去<your-.git-directory>/modules/foo (不是 .../foo.git )。如果 repo 中不存在某些模块,它不会崩溃,它只是跳过它。

还有改进的余地。它不处理子模块中的子模块,它只向下一层。它可能只改变子模块git wta调用git wtas打电话,但我还没有验证这一点。

-- clacke


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


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

参见 commit 00a6d4d (2019 年 1 月 5 日)作者:Nguyễn Thái Ngọc Duy ( pclouds ) .
(由 Junio C Hamano -- gitster -- merge 于 commit 726f89c ,2019 年 1 月 18 日)

worktree: allow to (re)move worktrees with uninitialized submodules

Uninitialized submodules have nothing valuable for us to be worried about. They are just SHA-1.
Let "worktree remove" and "worktree move" continue in this case so that people can still use multiple worktrees on repos with optional submodules that are never populated, like sha1collisiondetection in git.git when checked out by doc-diff script.

Note that for "worktree remove", it is possible that a user initializes a submodule (*), makes some commits (but not push), then deinitializes it.
At that point, the submodule is unpopulated, but the precious new commits are still in:

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

directory and we should not allow removing the worktree or we lose those commits forever.
The new directory check is added to prevent this.

(*) yes they are screwed anyway by doing this since "git submodule" would add submodule.* in $GIT_COMMON_DIR/config, which is shared across multiple worktrees.
But it does not mean we let them be screwed even more.


在 Git 2.25(2020 年第一季度)之前,如果你有 submodule.recurse配置选项集,发出 git worktree add在具有初始化子模块的 super 项目中会失败。

参见 commit 4782cf2ab6 (2019 年 10 月 27 日)Philippe Blain ( phil-blain ) .
(由 Junio C Hamano -- gitster -- merge 于 commit 726f89c ,2019 年 12 月 1 日)

worktree: teach "add" to ignore submodule.recurse config

"worktree add" internally calls "reset --hard", but if submodule.recurse is set, reset tries to recurse into initialized submodules, which makes start_command try to cd into non-existing submodule paths and die.

Fix that by making sure that the call to reset in "worktree add" does not recurse.

早期版本的解决方法是暂时停用配置:

git -c submodule.recurse=0 worktree add ...

Git 2.26(2020 年第 2 季度)之前,发布 git checkout --recurse-submodules (或 resetread-tree )在具有初始化子模块的 repo 的链接工作树中会错误地移动 main 工作树的 git 存储库中的子模块 HEAD,并破坏.git链接工作树中子模块工作目录中的 .gitfile:

参见 commit a9472afb63 (2020 年 1 月 21 日)Philippe Blain ( phil-blain ) .
(由 Junio C Hamano -- gitster -- merge 于 commit ff5134b2,2020 年 1 月 5 日)

submodule.c: use get_git_dir() instead of get_git_common_dir()

Ever since df56607 (git-common-dir: make "modules/" per-working-directory directory, 2014-11-30), submodules in linked worktrees are cloned to $GIT_DIR/modules, i.e. $GIT_COMMON_DIR/worktrees/<name>/modules.

However, this convention was not followed when the worktree updater commands checkout, reset and read-tree learned to recurse into submodules. Specifically, submodule.c::submodule_move_head, introduced in 6e3c159 (update submodules: add submodule_move_head, 2017-03-14) and submodule.c::submodule_unset_core_worktree, (re)introduced in 898c2e6 (submodule: unset core.worktree if no working tree is present, 2018-12-14) use get_git_common_dir() instead of get_git_dir() to get the path of the submodule repository.

This means that, for example, 'git checkout --recurse-submodules <branch>' in a linked worktree will correctly checkout <branch>, detach the submodule's HEAD at the commit recorded in <branch> and update the submodule working tree, but the submodule HEAD that will be moved is the one in $GIT_COMMON_DIR/modules/<name>/, i.e. the submodule repository of the main superproject working tree. It will also rewrite the gitfile in the submodule working tree of the linked worktree to point to $GIT_COMMON_DIR/modules/<name>/. This leads to an incorrect (and confusing!) state in the submodule working tree of the main superproject worktree.

Additionally, if switching to a commit where the submodule is not present, submodule_unset_core_worktree will be called and will incorrectly remove 'core.wortree' from the config file of the submodule in the main superproject worktree, $GIT_COMMON_DIR/modules/<name>/config.

Fix this by constructing the path to the submodule repository using get_git_dir() in both submodule_move_head and submodule_unset_core_worktree.

关于git - 将 git worktree 与 git 子模块一起使用时出了什么问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31871888/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com