Scenario: submodule-in-linked-worktree
A submodule, checked out in the monorepo and in a linked worktree of it.
- Monorepo, on
main:vendor/a/is a submodule of the upstream, checked out. - Linked worktree
../feature/, onfeature: the same submodule, initialized and checked out there too. - Upstream:
seed.
Converting the submodule on main removes its settings,
submodule.<name>.*, from .git/config. All worktrees share that file,
so the submodule in ../feature/ counts as uninitialized from then on.
Git itself advises against several worktrees of a monorepo with
submodules: "the support for submodules is incomplete", says the
git worktree documentation.
Output
setup.bash builds this state:
$ build_scenario scenario_submodule_in_linked_worktree
Before, the other worktree has the submodule initialized:
$ git -C ../feature submodule status
bde416459fbcc09c9b585f3b65a94cab3f68bfcd vendor/a (heads/main)
$ git splice clone --from-submodule vendor/a
=== vendor/a: fetching $UPSTREAM
ok vendor/a: cloned bde4164 from the submodule
=== vendor/a: the submodule's repository stays in .*/monorepo/\.git/modules/vendor/a -- remove it once you don't need it (regex)
After, the submodule's settings are gone, for every worktree:
$ git config --get-regexp '^submodule\.' || echo "no submodule settings"
no submodule settings
$ git -C ../feature submodule status
-bde416459fbcc09c9b585f3b65a94cab3f68bfcd vendor/a
../feature/ still has the files, but git submodule update skips the
submodule until git submodule update --init sets it up again:
$ ls ../feature/vendor/a
file.txt
$ git -C ../feature submodule update && git -C ../feature submodule status
-bde416459fbcc09c9b585f3b65a94cab3f68bfcd vendor/a
Merging main into feature fails like in every checkout that has the
submodule's files, a colleague's clone too: from the merge's view they're
untracked files in the way.
$ git -C ../feature merge -q main
error: The following untracked working tree files would be overwritten by merge:
vendor/a/file.txt
Please move or remove them before you merge.
Aborting
[1]
git submodule deinit -f removes the checkout, also here, where the
submodule's settings are gone already. Then the merge converts the
submodule in feature too:
$ git -C ../feature submodule deinit -q -f vendor/a && git -C ../feature merge -q main && git -C ../feature status --short && ls -A ../feature/vendor/a
.splice
file.txt