Commit 07a84fe5 authored by Duy Nguyen's avatar Duy Nguyen

doc: outline how submodules work with multi worktrees

This lays out the very first step of making multiple worktrees and
submodules work together. No actual changes are here. And real changes
are not even in the very next patches since they are cleanup and
preparation patches.

When a submodule is added to a superproject, the superproject's config
file records info related to the submodule in its config file. The
submodule's config file also has core.worktree to point back to the
submodule worktree's location.

Since config files are shared without extensions.worktreeConfig, adding
a secondary superproject or submodule worktree will run into trouble [1].
The problem could be solved with extensions.worktreeConfig and we keep
per-worktree config in config.worktree files, both at superproject
(submodule.*.*) and submodule (core.worktree) levels.

The whole directory layout would look like this. This shows how
multiple worktrees of a submodule or a supermodule are organized:

    config                           contains shared submodule.*
    config.worktree                  contains submodule.sub1.*
                                     for the main worktree
      super1/                   (1)
        config.worktree              submodule.sub1.* for super1
          sub1/                 (2)
            config.worktree          contains core.worktree
            objects/            (3)
            worktrees/          (4)
      super2/                   (5)
        config.worktree              submodule.sub1.* for super2
          sub1/                 (6)
            config.worktree          contains core.worktree
            objects/            (7)
    .git                     -> (1)
      .git                   -> (2)
      .git                   -> (4)/wt1
      .git                   -> (4)/wt2
    .git                     -> (5)
      .git                   -> (6)

This directory layout works, but not optimal. Submodule clones (inside
the "modules" directory) are per-worktree. If you have two
superproject worktrees that contain a submodule, you need space for
_two_ clones, e.g. the object databases (3) and (7) are almost
identical, but they are still duplicated.

This is definitely not elegant. The tentative plan is to move the
clones to a common tree like below. This is however just an idea and
not implemented in this series.

    config                           contains shared submodule.*
        sub1/                   (0)
          objects/              (shared)
            super1/             (2)
            super1-wt1/         (4)/wt1
            super1-wt2/         (4)/wt2
            super2/             (6)
      super1/                   (1)
        config.worktree              submodule.sub1.* for super1
      super2/                   (5)
        config.worktree              submodule.sub1.* for super2

The subtree (0) is shared across all worktrees because it's inside
"common/" directory. Once we keep the clone in a common place like
this, the submodule's worktree can be created and managed with

Another good point about this approach is we could finally safely
allow "git worktree remove" to work with submodules. With current
solution, removing $GIT_COMMON_DIR/worktrees/X directory means also
removing potentially precious clones inside the "modules" subdir.

But whether we can do this depends on:

- if we need separate ref namespace for submodule on each worktree.
  Use cases that can share ref namespace will work best.

- how does submodule's worktrees interact these worktrees

- handling nested submodules can get very messy (or not?)

This series does not attempt to implement subtree (0) at all. Once we
get submodules and worktrees work well together (even wasteful of disk
space), we can start thinking about absorbing clones back to common/

[1] It's milder for secondary submodule worktree because core.worktree
    will not be shared (core.worktree by default is only visible to
    the main worktree). But then the second worktree cannot have its
    own core.worktree.
parent 83232e38
......@@ -263,6 +263,12 @@ do not want to share to all working trees:
- `core.sparseCheckout` is recommended per working tree, unless you
are sure you always use sparse checkout for all working trees.
- Most configuration variables under `submodule` group in superproject
should not be shared.
- If you use submodules, you may need to move `core.worktree` in each
submodule as well
Each linked working tree has a private sub-directory in the repository's
......@@ -222,6 +222,23 @@ submodule active pathspec, which specifies that any submodule
starting with 'b' except 'baz' are also active, regardless of the
presence of the .url field.
When you have more than one working tree, created by
linkgit:git-worktree[1], submodules will not work on any working tree
until `extensions.worktreeConfig` is enabled. Since this config
affects more than just submodules, please see "CONFIGURATION FILE"
section for more information before turning it on.
Once on, submodules can be added in any working tree. The submodule
itself though cannot have more than one working tree.
When submodules are created in a working tree, their git directory is
also per-worktree, e.g. inside
'$GIT_COMMON_DIR/worktrees/<worktree>/modules' and not shared with
other working trees. This means if you have the same submodule on
different working trees, you need disk space for multiple clones.
Workflow for a third party library
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment