diff mbox series

[01/10] doc: about submodule support with multiple worktrees

Message ID 20190116103159.9305-2-pclouds@gmail.com (mailing list archive)
State New, archived
Headers show
Series Support using submodules with worktrees | expand

Commit Message

Duy Nguyen Jan. 16, 2019, 10:31 a.m. UTC
This lays out the very first step of making multiple worktrees and
submodules work together.

The first problem is git-submodule keeps per-worktree config in
$GIT_DIR/config, which is shared for all worktrees. This series makes
git-submodule use extensions.worktreeConfig and write submodule.* to
config.worktree instead.

The rest goes on and on about the remaining problems. But let's talk a
bit more about solving the first problem. Since it relies on the
experimental extensions.worktreeConfig, this support is of course also
experimental. On the other hand, submodules have never really worked
with multi worktrees before, this change can't bite anybody.

Second problem. That is about multiple worktrees at superproject
level. At submodule level, we still can't have multiple worktrees
because git-submodule writes to submodule's "config" file
(again). Fixing this is not particularly hard. Absorbing submodule's
git dir takes some work but is feasible. This could be addressed soon
in the future.

The third problem is a big and complicaed one. Submodule clones
(inside the superproject) are per-worktree. So if you have two
worktrees, and these have one submodule, you need space for _two_
clones. This is definitely not elegant. The tenative plan is to move
clones from $GIT_COMMON_DIR/worktrees/X/modules to
$GIT_COMMON_DIR/common/modules.

The latter directory is shared across all worktrees. Once we keep the
clone in a common place, the submodule's worktree can be created and
managed with git-worktree[1].

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

- how does submodule's worktrees (remember the second problem)
  interact these worktrees

Signed-off-by: Nguyễn Thái Ngọc Duy <pclouds@gmail.com>
---
 Documentation/git-worktree.txt  |  8 ++++++++
 Documentation/gitsubmodules.txt | 17 +++++++++++++++++
 2 files changed, 25 insertions(+)

Comments

Stefan Beller Jan. 16, 2019, 10:06 p.m. UTC | #1
> The third problem is a big and complicaed one. Submodule clones

complicated

> (inside the superproject) are per-worktree. So if you have two
> worktrees, and these have one submodule, you need space for _two_
> clones. This is definitely not elegant. The tenative plan is to move

tentative?

> clones from $GIT_COMMON_DIR/worktrees/X/modules to
> $GIT_COMMON_DIR/common/modules.

... from the submodule side of things this is big problem,
as the submodule is usually assumed at $GIT_DIR/modules/<name>
(I think we have not been strict in $GIT_DIR $GIT_COMMON_DIR
in the submodule code)

So the plan is to neither use
$GIT_COMMON_DIR/worktrees/X/modules/Y
$GIT_COMMON_DIR/modules/Y/worktrees/X
but to create a new third location at
$GIT_COMMON_DIR/common/modules
to which either new submodule worktrees
or superproject worktrees that happen to have this submodule
can point to?

>
> The latter directory is shared across all worktrees. Once we keep the
> clone in a common place, the submodule's worktree can be created and
> managed with git-worktree[1].

So even when the user has never heard of worktrees, the internal structure
will be worktree oriented, the common dir in common/modules/Y and in
$GIT_DIR/modules/Y we could just have a worktree git dir?

> 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.

yup, very sensible.

I like this approach very much.
Duy Nguyen Jan. 17, 2019, 10:22 a.m. UTC | #2
On Thu, Jan 17, 2019 at 5:06 AM Stefan Beller <sbeller@google.com> wrote:
> > clones from $GIT_COMMON_DIR/worktrees/X/modules to
> > $GIT_COMMON_DIR/common/modules.
>
> ... from the submodule side of things this is big problem,
> as the submodule is usually assumed at $GIT_DIR/modules/<name>
> (I think we have not been strict in $GIT_DIR $GIT_COMMON_DIR
> in the submodule code)
>
> So the plan is to neither use
>
> $GIT_COMMON_DIR/worktrees/X/modules/Y
> $GIT_COMMON_DIR/modules/Y/worktrees/X
>
> but to create a new third location at
>
> $GIT_COMMON_DIR/common/modules
>
> to which either new submodule worktrees
> or superproject worktrees that happen to have this submodule
> can point to?

Yes. And this is yet another "absorb" operation to move from the
current location to the new one. The code will have to check both
places, just as it has to check if "foo/bar/.git" is a real repo
before it goes to $GIT_DIR/.git/modules/bar (at least this is how I
understand it).

> > The latter directory is shared across all worktrees. Once we keep the
> > clone in a common place, the submodule's worktree can be created and
> > managed with git-worktree[1].
>
> So even when the user has never heard of worktrees, the internal structure
> will be worktree oriented, the common dir in common/modules/Y and in
> $GIT_DIR/modules/Y we could just have a worktree git dir?

I think the .git dir will be in common/modules/Y. $GIT_DIR/modules/Y
is basically replaced by $GIT_COMMON_DIR/common/modules/Y, which
should work even when you don't use git-worktree (in single-worktree
setting, $GIT_COMMON_DIR == $GIT_DIR).
diff mbox series

Patch

diff --git a/Documentation/git-worktree.txt b/Documentation/git-worktree.txt
index aae8e1d8b2..3510fd5331 100644
--- a/Documentation/git-worktree.txt
+++ b/Documentation/git-worktree.txt
@@ -267,6 +267,14 @@  configuration that you 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.
++
+------------
+$ git config --local --move-to --worktree submodule.active
+$ git config --local --move-to-regexp --worktree 'submodule\..*\..*'
+------------
+
 DETAILS
 -------
 Each linked working tree has a private sub-directory in the repository's
diff --git a/Documentation/gitsubmodules.txt b/Documentation/gitsubmodules.txt
index 57999e9f36..d91817b45d 100644
--- a/Documentation/gitsubmodules.txt
+++ b/Documentation/gitsubmodules.txt
@@ -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.
 
+MULTIPLE WORKING TREE SUPPORT
+-----------------------------
+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
 ----------------------------------