init: Add --use-local-gitdirs for standard Git layouts

Introduce --use-local-gitdirs to bypass repo's symlink-based layouts in
favor of standard local .git directories.

Bug: 513329573
Bug: 508146070
Change-Id: I53d1602e61be0b86964529bcbea3dc801471f9c9
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/569001
Tested-by: Gavin Mak <gavinmak@google.com>
Commit-Queue: Gavin Mak <gavinmak@google.com>
Reviewed-by: Dan Willemsen <dwillemsen@google.com>
This commit is contained in:
Gavin Mak
2026-04-03 01:11:35 +00:00
committed by gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 2d54384a5e
commit b8531133de
7 changed files with 144 additions and 10 deletions
+44 -1
View File
@@ -3686,7 +3686,11 @@ class Project:
self._MigrateOldSubmoduleDir()
# 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)
and not self.manifest.UseLocalGitDirs
):
self._MigrateOldWorkTreeGitDir(dotgit, project=self.name)
init_dotgit = not os.path.lexists(dotgit)
@@ -3735,6 +3739,11 @@ class Project:
For submodule projects, create a '.git' file using the gitfile
mechanism, and for the rest, create a symbolic link.
"""
if self.manifest.UseLocalGitDirs and os.path.normpath(
self.gitdir
) == os.path.normpath(dotgit):
return
os.makedirs(self.worktree, exist_ok=True)
if self.parent:
_lwrite(
@@ -4488,6 +4497,11 @@ class ManifestProject(MetaProject):
"""Whether we use worktree."""
return self.config.GetBoolean("repo.worktree")
@property
def use_local_gitdirs(self):
"""Whether we use local gitdirs."""
return self.config.GetBoolean("repo.uselocalgitdirs")
@property
def clone_bundle(self):
"""Whether we use clone_bundle."""
@@ -4642,6 +4656,7 @@ class ManifestProject(MetaProject):
this_manifest_only=False,
outer_manifest=True,
clone_filter_for_depth=None,
use_local_gitdirs=False,
):
"""Sync the manifest and all submanifests.
@@ -4872,6 +4887,34 @@ class ManifestProject(MetaProject):
self.use_git_worktrees = True
logger.warning("warning: --worktree is experimental!")
if use_local_gitdirs:
if mirror:
logger.error(
"fatal: --mirror and --use-local-gitdirs are incompatible"
)
return False
if worktree:
logger.error(
"fatal: --worktree and --use-local-gitdirs are incompatible"
)
return False
if archive:
logger.error(
"fatal: --archive and --use-local-gitdirs are incompatible"
)
return False
if not is_new and not self.use_local_gitdirs:
logger.error(
"fatal: --use-local-gitdirs is only supported when "
"initializing a new workspace."
)
return False
self.config.SetBoolean("repo.uselocalgitdirs", use_local_gitdirs)
if archive:
if is_new:
self.config.SetBoolean("repo.archive", archive)