diff options
author | Kaushik Lingarkar <kaushikl@qti.qualcomm.com> | 2024-12-17 13:49:19 -0800 |
---|---|---|
committer | Kaushik Lingarkar <kaushikl@qti.qualcomm.com> | 2025-02-04 08:07:49 -0800 |
commit | 66685f07ecf1b8bc228df66ea0d29fd7086e18e7 (patch) | |
tree | 8f8d3420fc102a1f91187164c4628395dd2ae223 | |
parent | cf9a2a2a76b332c89fef40e47f7ddb4e8c817ab9 (diff) | |
download | git-repo-66685f07ecf1b8bc228df66ea0d29fd7086e18e7.tar.gz |
Use 'gitfile' in submodule checkouts
This change takes another step towards ensuring Git can understand
repo's submodules to some extent. Replace the old '.git' symlink with
gitfile[1] pointing to the bare checkout of the submodule. This is
required for Git's 'recurse submodules' opts to work with repo's
submodules as '.git' is expected to be writable by Git when recursing
over submodules.
[1] https://git-scm.com/docs/gitrepository-layout#_description
Change-Id: I52d15451768ee7bd6db289f4d2b3be5907370d42
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/446181
Tested-by: Kaushik Lingarkar <kaushikl@qti.qualcomm.com>
Reviewed-by: Josip Sokcevic <sokcevic@chromium.org>
Reviewed-by: Mike Frysinger <vapier@google.com>
Reviewed-by: Nasser Grainawi <nasser.grainawi@oss.qualcomm.com>
-rw-r--r-- | project.py | 49 |
1 files changed, 42 insertions, 7 deletions
@@ -3430,20 +3430,21 @@ class Project: | |||
3430 | self._InitGitWorktree() | 3430 | self._InitGitWorktree() |
3431 | self._CopyAndLinkFiles() | 3431 | self._CopyAndLinkFiles() |
3432 | else: | 3432 | else: |
3433 | # Remove old directory symbolic links for submodules. | ||
3434 | if self.parent and platform_utils.islink(dotgit): | ||
3435 | platform_utils.remove(dotgit) | ||
3436 | init_dotgit = True | ||
3437 | |||
3433 | if not init_dotgit: | 3438 | if not init_dotgit: |
3434 | # See if the project has changed. | 3439 | # See if the project has changed. |
3435 | if os.path.realpath(self.gitdir) != os.path.realpath(dotgit): | 3440 | self._removeBadGitDirLink(dotgit) |
3436 | platform_utils.remove(dotgit) | ||
3437 | 3441 | ||
3438 | if init_dotgit or not os.path.exists(dotgit): | 3442 | if init_dotgit or not os.path.exists(dotgit): |
3439 | os.makedirs(self.worktree, exist_ok=True) | 3443 | self._createDotGit(dotgit) |
3440 | platform_utils.symlink( | ||
3441 | os.path.relpath(self.gitdir, self.worktree), dotgit | ||
3442 | ) | ||
3443 | 3444 | ||
3444 | if init_dotgit: | 3445 | if init_dotgit: |
3445 | _lwrite( | 3446 | _lwrite( |
3446 | os.path.join(dotgit, HEAD), "%s\n" % self.GetRevisionId() | 3447 | os.path.join(self.gitdir, HEAD), f"{self.GetRevisionId()}\n" |
3447 | ) | 3448 | ) |
3448 | 3449 | ||
3449 | # Finish checking out the worktree. | 3450 | # Finish checking out the worktree. |
@@ -3465,6 +3466,40 @@ class Project: | |||
3465 | self._SyncSubmodules(quiet=True) | 3466 | self._SyncSubmodules(quiet=True) |
3466 | self._CopyAndLinkFiles() | 3467 | self._CopyAndLinkFiles() |
3467 | 3468 | ||
3469 | def _createDotGit(self, dotgit): | ||
3470 | """Initialize .git path. | ||
3471 | |||
3472 | For submodule projects, create a '.git' file using the gitfile | ||
3473 | mechanism, and for the rest, create a symbolic link. | ||
3474 | """ | ||
3475 | os.makedirs(self.worktree, exist_ok=True) | ||
3476 | if self.parent: | ||
3477 | _lwrite( | ||
3478 | dotgit, | ||
3479 | f"gitdir: {os.path.relpath(self.gitdir, self.worktree)}\n", | ||
3480 | ) | ||
3481 | else: | ||
3482 | platform_utils.symlink( | ||
3483 | os.path.relpath(self.gitdir, self.worktree), dotgit | ||
3484 | ) | ||
3485 | |||
3486 | def _removeBadGitDirLink(self, dotgit): | ||
3487 | """Verify .git is initialized correctly, otherwise delete it.""" | ||
3488 | if self.parent and os.path.isfile(dotgit): | ||
3489 | with open(dotgit) as fp: | ||
3490 | setting = fp.read() | ||
3491 | if not setting.startswith("gitdir:"): | ||
3492 | raise GitError( | ||
3493 | f"'.git' in {self.worktree} must start with 'gitdir:'", | ||
3494 | project=self.name, | ||
3495 | ) | ||
3496 | gitdir = setting.split(":", 1)[1].strip() | ||
3497 | dotgit_path = os.path.normpath(os.path.join(self.worktree, gitdir)) | ||
3498 | else: | ||
3499 | dotgit_path = os.path.realpath(dotgit) | ||
3500 | if os.path.realpath(self.gitdir) != dotgit_path: | ||
3501 | platform_utils.remove(dotgit) | ||
3502 | |||
3468 | @classmethod | 3503 | @classmethod |
3469 | def _MigrateOldWorkTreeGitDir(cls, dotgit, project=None): | 3504 | def _MigrateOldWorkTreeGitDir(cls, dotgit, project=None): |
3470 | """Migrate the old worktree .git/ dir style to a symlink. | 3505 | """Migrate the old worktree .git/ dir style to a symlink. |