{"thread":{"id":"65495","subject":"[PATCH 0/3] worktree: add --recurse-submodules support to git worktree add","startedAt":"2026-04-16T16:32:22Z","lastAt":"2026-04-17T09:38:23Z","messageCount":4,"participants":["Jimmy Aguilar Mena","Junio C Hamano","Phillip Wood"],"isPatch":true,"patchVersion":1,"patchTotal":3},"messages":[{"id":"541751","messageId":"aeEMU-ohKz2tnSWq@RTX","threadId":"65495","inReplyTo":null,"subject":"[PATCH 0/3] worktree: add --recurse-submodules support to git worktree add","fromName":"Jimmy Aguilar Mena","fromEmail":"kratsbinovish@gmail.com","sentAt":"2026-04-16T16:32:18Z","receivedAt":"2026-04-16T16:32:22Z","isPatch":true,"body":"This series implements the native --recurse-submodules flag for\n\"git worktree add\" discussed in the earlier RFC thread.\n\nThe approach follows Phillip Wood's and Junio's feedback: each linked\nworktree gets its own per-worktree submodule gitdir under\n$GIT_COMMON_DIR/worktrees/<id>/modules/<name>/, so HEAD, refs, and\nthe index are independent per worktree while pack files and loose\nobjects are shared via hardlinks.  The gitdir isolation is the same\nmodel git worktree already uses for the superproject.\n\nPatch 1 adds the --recurse-submodules flag to builtin/worktree.c and\ncalls \"git submodule update --init --recursive\" from within the new\nworktree after checkout.\n\nPatch 2 teaches clone_submodule() in builtin/submodule--helper.c to\ndetect when the main worktree already has the submodule cloned and\nreuse it via \"git clone --local --no-checkout --separate-git-dir\"\ninstead of fetching from the remote URL.  This avoids redundant\nnetwork access and disk use: the objects are already present locally.\n\nPatch 3 adds tests to t2405-worktree-submodule.sh covering both the\nhappy path and the gitdir-isolation invariant.\n\nCleanup is automatic: submodule gitdirs under worktrees/<id>/modules/\nare removed when \"git worktree remove\" calls remove_dir_recursively()\non the worktree entry, exactly as with the superproject's per-worktree\nstate.\n\nChanges since the RFC:\n- Replaced the shell-script cp -al prototype with a native C\n   implementation in builtin/worktree.c and builtin/submodule--helper.c.\n- Per-worktree gitdir isolation is now handled by the existing\n   submodule_name_to_gitdir() path; no extra plumbing is needed.\n- Added t2405 tests verifying both behaviour and gitdir placement.\n\nJimmy Aguilar Mena (3):\n   worktree: add --recurse-submodules flag to worktree add\n   submodule--helper: reuse main-worktree gitdir in linked worktrees\n   t2405: add tests for worktree add --recurse-submodules\n\n  builtin/submodule--helper.c   | 54 +++++++++++++++++++++++++++++++++++\n  builtin/worktree.c            | 23 +++++++++++++++\n  t/t2405-worktree-submodule.sh | 24 +++++++++++++++-\n  3 files changed, 100 insertions(+), 1 deletion(-)\n"},{"id":"541756","messageId":"xmqqzf3225u1.fsf@gitster.g","threadId":"65495","inReplyTo":"aeEMU-ohKz2tnSWq@RTX","subject":"Re: [PATCH 0/3] worktree: add --recurse-submodules support to git worktree add","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-04-16T17:05:58Z","receivedAt":"2026-04-16T17:06:01Z","isPatch":true,"body":"Jimmy Aguilar Mena <kratsbinovish@gmail.com> writes:\n\n> The approach follows Phillip Wood's and Junio's feedback: each linked\n> worktree gets its own per-worktree submodule gitdir under\n> $GIT_COMMON_DIR/worktrees/<id>/modules/<name>/, so HEAD, refs, and\n> the index are independent per worktree while pack files and loose\n> objects are shared via hardlinks.  The gitdir isolation is the same\n> model git worktree already uses for the superproject.\n\nI do not quite follow.  The point of git-native worktree support\n(which improved a lot compared to its precursor, \"git-new-workdir\",\nis that it can work well in a hardlink-challenged platforms.  You\nshouldn't worry about \"hardlinking\" yourself at all.\n\nAfter the superproject successfully did \"submodule init\", you can\nmove the submodule's repository with \"absorbgitdirs\" to\n$GIT_DIR/modules/<submodule>/ of the superproject.  The primary\nmotivation behind this feature was that you can switch to a commit\nin the superproject that does *not* have the submodule bound to it\nat all (and obviously you do not want to lose the submodule\nrepository only because you tentatively switch to such a commit and\nhave to re-download when you switch back), but I think it gives the\nsingle instance of submodule repository that you can share across\nworktrees of the submodule.  Because the single directory created\nwith \"absorbgitdirs\" looks like a bare repository, you should be\nable to create two worktrees off of that, with their own HEAD etc.\n"},{"id":"541763","messageId":"19b86e02-6842-42f0-8226-c86ad6669ec4@gmail.com","threadId":"65495","inReplyTo":"xmqqzf3225u1.fsf@gitster.g","subject":"Re: [PATCH 0/3] worktree: add --recurse-submodules support to git worktree add","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-04-16T18:38:12Z","receivedAt":"2026-04-16T18:38:18Z","isPatch":true,"body":"On 16/04/2026 18:05, Junio C Hamano wrote:\n> Jimmy Aguilar Mena <kratsbinovish@gmail.com> writes:\n> \n>> The approach follows Phillip Wood's and Junio's feedback: each linked\n>> worktree gets its own per-worktree submodule gitdir under\n>> $GIT_COMMON_DIR/worktrees/<id>/modules/<name>/, so HEAD, refs, and\n>> the index are independent per worktree while pack files and loose\n>> objects are shared via hardlinks.  The gitdir isolation is the same\n>> model git worktree already uses for the superproject.\n> \n> I do not quite follow.  The point of git-native worktree support\n> (which improved a lot compared to its precursor, \"git-new-workdir\",\n> is that it can work well in a hardlink-challenged platforms.  You\n> shouldn't worry about \"hardlinking\" yourself at all.\n> \n> After the superproject successfully did \"submodule init\", you can\n> move the submodule's repository with \"absorbgitdirs\" to\n> $GIT_DIR/modules/<submodule>/ of the superproject.  The primary\n> motivation behind this feature was that you can switch to a commit\n> in the superproject that does *not* have the submodule bound to it\n> at all (and obviously you do not want to lose the submodule\n> repository only because you tentatively switch to such a commit and\n> have to re-download when you switch back), but I think it gives the\n> single instance of submodule repository that you can share across\n> worktrees of the submodule.  Because the single directory created\n> with \"absorbgitdirs\" looks like a bare repository, you should be\n> able to create two worktrees off of that, with their own HEAD etc.\n\nI haven't thought much about it but that would mean that \"git worktree \nremove\" ought to remove the submodule's worktree when the worktree \ncontaining the submodule is removed. Worktrees avoid hardlinks by \ncreating a \"commondir\" file in the worktree's gitdir which contains the \nrelative path to \"$GIT_COMMON_DIR\". I think we could probably do the \nsame here and create \n\"$GIT_COMMON_DIR/worktrees/<id>/modules/<name>/commondir\" containing \n\"../../../../modules/<name>\" if we want to store the submodule's gitdir \nunder the worktree's gitdir. That way removing a worktree's gitdir \nremoves all the gitdirs of its submodules without any extra effort. \nThere are probably other tradeoffs between the two approaches that I've \nnot thought of.\n\nThanks\n\nPhillip\n\n"},{"id":"541810","messageId":"9f46e619-2f34-465f-8bb8-6688f8b56cc0@gmail.com","threadId":"65495","inReplyTo":"19b86e02-6842-42f0-8226-c86ad6669ec4@gmail.com","subject":"Re: [PATCH 0/3] worktree: add --recurse-submodules support to git worktree add","fromName":"Phillip Wood","fromEmail":"phillip.wood123@gmail.com","sentAt":"2026-04-17T09:38:18Z","receivedAt":"2026-04-17T09:38:23Z","isPatch":true,"body":"On 16/04/2026 19:38, Phillip Wood wrote:\n> On 16/04/2026 18:05, Junio C Hamano wrote:\n>> Jimmy Aguilar Mena <kratsbinovish@gmail.com> writes:\n>>\n>>> The approach follows Phillip Wood's and Junio's feedback: each linked\n>>> worktree gets its own per-worktree submodule gitdir under\n>>> $GIT_COMMON_DIR/worktrees/<id>/modules/<name>/, so HEAD, refs, and\n>>> the index are independent per worktree while pack files and loose\n>>> objects are shared via hardlinks.  The gitdir isolation is the same\n>>> model git worktree already uses for the superproject.\n>>\n>> I do not quite follow.  The point of git-native worktree support\n>> (which improved a lot compared to its precursor, \"git-new-workdir\",\n>> is that it can work well in a hardlink-challenged platforms.  You\n>> shouldn't worry about \"hardlinking\" yourself at all.\n>>\n>> After the superproject successfully did \"submodule init\", you can\n>> move the submodule's repository with \"absorbgitdirs\" to\n>> $GIT_DIR/modules/<submodule>/ of the superproject.  The primary\n>> motivation behind this feature was that you can switch to a commit\n>> in the superproject that does *not* have the submodule bound to it\n>> at all (and obviously you do not want to lose the submodule\n>> repository only because you tentatively switch to such a commit and\n>> have to re-download when you switch back), but I think it gives the\n>> single instance of submodule repository that you can share across\n>> worktrees of the submodule.  Because the single directory created\n>> with \"absorbgitdirs\" looks like a bare repository, you should be\n>> able to create two worktrees off of that, with their own HEAD etc.\n> \n> I haven't thought much about it but that would mean that \"git worktree \n> remove\" ought to remove the submodule's worktree when the worktree \n> containing the submodule is removed. Worktrees avoid hardlinks by \n> creating a \"commondir\" file in the worktree's gitdir which contains the \n> relative path to \"$GIT_COMMON_DIR\". I think we could probably do the \n> same here and create \"$GIT_COMMON_DIR/worktrees/<id>/modules/<name>/ \n> commondir\" containing \"../../../../modules/<name>\" if we want to store \n> the submodule's gitdir under the worktree's gitdir. That way removing a \n> worktree's gitdir removes all the gitdirs of its submodules without any \n> extra effort. There are probably other tradeoffs between the two \n> approaches that I've not thought of.\n\nI've realized that creating the submodule's gitdir under the worktree's \ngitdir means that \"git gc\" running in the submodule repository wont see \nthe per-worktree refs and index file and will happily prune those \nobjects. Junio's suggestion avoids that problem.\n\nThanks\n\nPhillip\n\n"}]}