Update internal filesystem layout for submodules

Change the bare checkout directory for submodules from 'subprojects'
to 'modules'. Git expects bare submodule checkouts to be in the
'modules' directory. If old subproject directories are found, they
will be migrated to the new modules directory. This change is the
first step in ensuring Git can understand repo's submodules to some
extent.

Change-Id: I385029f1bb55d040616d970d6ffb4bb856692520
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/444881
Tested-by: Kaushik Lingarkar <kaushikl@qti.qualcomm.com>
Reviewed-by: Josip Sokcevic <sokcevic@chromium.org>
This commit is contained in:
Kaushik Lingarkar 2024-12-17 12:49:14 -08:00
parent 5ae8292fea
commit cf9a2a2a76
3 changed files with 34 additions and 2 deletions

View File

@ -141,7 +141,7 @@ Instead, you should use standard Git workflows like [git worktree] or
(e.g. a local mirror & a public review server) while avoiding duplicating (e.g. a local mirror & a public review server) while avoiding duplicating
the content. However, this can run into problems if different remotes use the content. However, this can run into problems if different remotes use
the same path on their respective servers. Best to avoid that. the same path on their respective servers. Best to avoid that.
* `subprojects/`: Like `projects/`, but for git submodules. * `modules/`: Like `projects/`, but for git submodules.
* `subproject-objects/`: Like `project-objects/`, but for git submodules. * `subproject-objects/`: Like `project-objects/`, but for git submodules.
* `worktrees/`: Bare checkouts of every project synced by the manifest. The * `worktrees/`: Bare checkouts of every project synced by the manifest. The
filesystem layout matches the `<project name=...` setting in the manifest filesystem layout matches the `<project name=...` setting in the manifest

View File

@ -2056,7 +2056,12 @@ https://gerrit.googlesource.com/git-repo/+/HEAD/docs/manifest-format.md
path = path.rstrip("/") path = path.rstrip("/")
name = name.rstrip("/") name = name.rstrip("/")
relpath = self._JoinRelpath(parent.relpath, path) relpath = self._JoinRelpath(parent.relpath, path)
gitdir = os.path.join(parent.gitdir, "subprojects", "%s.git" % path) subprojects = os.path.join(parent.gitdir, "subprojects", f"{path}.git")
modules = os.path.join(parent.gitdir, "modules", path)
if platform_utils.isdir(subprojects):
gitdir = subprojects
else:
gitdir = modules
objdir = os.path.join( objdir = os.path.join(
parent.gitdir, "subproject-objects", "%s.git" % name parent.gitdir, "subproject-objects", "%s.git" % name
) )

View File

@ -3415,6 +3415,11 @@ class Project:
""" """
dotgit = os.path.join(self.worktree, ".git") dotgit = os.path.join(self.worktree, ".git")
# If bare checkout of the submodule is stored under the subproject dir,
# migrate it.
if self.parent:
self._MigrateOldSubmoduleDir()
# If using an old layout style (a directory), migrate it. # If using an old layout style (a directory), migrate it.
if not platform_utils.islink(dotgit) and platform_utils.isdir(dotgit): if not platform_utils.islink(dotgit) and platform_utils.isdir(dotgit):
self._MigrateOldWorkTreeGitDir(dotgit, project=self.name) self._MigrateOldWorkTreeGitDir(dotgit, project=self.name)
@ -3548,6 +3553,28 @@ class Project:
dotgit, dotgit,
) )
def _MigrateOldSubmoduleDir(self):
"""Move the old bare checkout in 'subprojects' to 'modules'
as bare checkouts of submodules are now in 'modules' dir.
"""
subprojects = os.path.join(self.parent.gitdir, "subprojects")
if not platform_utils.isdir(subprojects):
return
modules = os.path.join(self.parent.gitdir, "modules")
old = self.gitdir
new = os.path.splitext(self.gitdir.replace(subprojects, modules))[0]
if all(map(platform_utils.isdir, [old, new])):
platform_utils.rmtree(old, ignore_errors=True)
else:
os.makedirs(modules, exist_ok=True)
platform_utils.rename(old, new)
self.gitdir = new
self.UpdatePaths(self.relpath, self.worktree, self.gitdir, self.objdir)
if platform_utils.isdir(subprojects) and not os.listdir(subprojects):
platform_utils.rmtree(subprojects, ignore_errors=True)
def _get_symlink_error_message(self): def _get_symlink_error_message(self):
if platform_utils.isWindows(): if platform_utils.isWindows():
return ( return (