-
Duy Nguyen authored
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: .git/ config contains shared submodule.* config.worktree contains submodule.sub1.* for the main worktree worktrees/ super1/ (1) config.worktree submodule.sub1.* for super1 modules/ sub1/ (2) config.worktree contains core.worktree objects/ (3) worktrees/ (4) wt1/ wt2/ super2/ (5) config.worktree submodule.sub1.* for super2 modules sub1/ (6) config.worktree contains core.worktree objects/ (7) super1/ .git -> (1) sub1/ .git -> (2) sub1-wt1/ .git -> (4)/wt1 sub1-wt2/ .git -> (4)/wt2 super2/ .git -> (5) sub1/ .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. .git/ config contains shared submodule.* objects/ common/ modules/ sub1/ (0) objects/ (shared) worktrees/ super1/ (2) super1-wt1/ (4)/wt1 super1-wt2/ (4)/wt2 super2/ (6) common/ modules/ nested-sub/... worktrees/ 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 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. 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.
07a84fe5