mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-08-31 03:46:17 +00:00
project: skip manifest default fallback for MetaProjects
Avoid loading manifest.xml during repo init when syncing a manifest commit SHA. Override _GetUpstreamFallback and _SharingProjectHasShallow in MetaProject to prevent premature manifest parsing. Bug: 544041102 Change-Id: I7aa54a7c1282e5bfe811d59e977b44163a37653c Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/617081 Commit-Queue: Gavin Mak <gavinmak@google.com> Tested-by: Gavin Mak <gavinmak@google.com> Reviewed-by: Brian Gan <brgan@google.com>
This commit is contained in:
committed by
gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent
d9da609d8c
commit
b85886fa9f
+25
-6
@@ -2859,12 +2859,17 @@ class Project:
|
||||
|
||||
def _GetUpstreamFallback(self) -> Optional[str]:
|
||||
"""Resolve a fallback upstream ref when revisionExpr is a SHA-1."""
|
||||
for cand in (
|
||||
self.dest_branch,
|
||||
self.manifest.default.upstreamExpr,
|
||||
self.manifest.default.destBranchExpr,
|
||||
self.manifest.default.revisionExpr,
|
||||
):
|
||||
default = self.manifest.default
|
||||
candidates = [self.dest_branch]
|
||||
if default:
|
||||
candidates.extend(
|
||||
(
|
||||
default.upstreamExpr,
|
||||
default.destBranchExpr,
|
||||
default.revisionExpr,
|
||||
)
|
||||
)
|
||||
for cand in candidates:
|
||||
if cand and not IsId(cand):
|
||||
return cand
|
||||
return None
|
||||
@@ -4737,6 +4742,20 @@ class MetaProject(Project):
|
||||
# before manifest.xml has been linked into .repo/.
|
||||
return False
|
||||
|
||||
def _GetUpstreamFallback(self) -> Optional[str]:
|
||||
# MetaProjects (the manifest repo and repo itself) do not have
|
||||
# defaults in a manifest. Returning None here also avoids
|
||||
# loading the manifest during `repo init`, before manifest.xml
|
||||
# has been linked into .repo/.
|
||||
return None
|
||||
|
||||
def _SharingProjectHasShallow(self) -> bool:
|
||||
# MetaProjects (the manifest repo and repo itself) are never
|
||||
# shared with other projects in the manifest. Returning False
|
||||
# here also avoids loading the manifest during `repo init`,
|
||||
# before manifest.xml has been linked into .repo/.
|
||||
return False
|
||||
|
||||
@property
|
||||
def HasChanges(self):
|
||||
"""Has the remote received new commits not yet checked out?"""
|
||||
|
||||
@@ -742,6 +742,35 @@ class ManifestPropertiesFetchedCorrectly(unittest.TestCase):
|
||||
)
|
||||
self.assertFalse(os.path.exists(manifest_path))
|
||||
|
||||
def test_get_upstream_fallback_metaproject_skips_manifest_load(
|
||||
self,
|
||||
) -> None:
|
||||
"""MetaProjects must not parse manifest.xml during upstream fallback."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
fakeproj = self.setUpManifest(tempdir)
|
||||
manifest_path = os.path.join(
|
||||
tempdir, ".repo", manifest_xml.MANIFEST_FILE_NAME
|
||||
)
|
||||
self.assertFalse(os.path.exists(manifest_path))
|
||||
|
||||
self.assertIsNone(fakeproj._GetUpstreamFallback())
|
||||
self.assertFalse(os.path.exists(manifest_path))
|
||||
|
||||
def test_sharing_project_has_shallow_metaproject_skips_manifest_load(
|
||||
self,
|
||||
) -> None:
|
||||
"""MetaProjects must not parse manifest.xml during sharing shallow
|
||||
check."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
fakeproj = self.setUpManifest(tempdir)
|
||||
manifest_path = os.path.join(
|
||||
tempdir, ".repo", manifest_xml.MANIFEST_FILE_NAME
|
||||
)
|
||||
self.assertFalse(os.path.exists(manifest_path))
|
||||
|
||||
self.assertFalse(fakeproj._SharingProjectHasShallow())
|
||||
self.assertFalse(os.path.exists(manifest_path))
|
||||
|
||||
def test_sync_use_local_gitdirs_worktree_conflict(self):
|
||||
"""Test that --use-local-gitdirs conflicts with --worktree."""
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
@@ -1403,6 +1432,61 @@ class SyncOptimizationTests(unittest.TestCase):
|
||||
"+refs/heads/*:refs/remotes/origin/*", cmd_args
|
||||
)
|
||||
|
||||
def test_remote_fetch_sha1_metaproject_without_manifest_xml(self) -> None:
|
||||
"""Test MetaProject _RemoteFetch with SHA-1 fetches all branches."""
|
||||
sha = "4f8a3c0000000000000000000000000000000000"
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
repodir = os.path.join(tempdir, ".repo")
|
||||
manifest_dir = os.path.join(repodir, "manifests")
|
||||
manifest_file = os.path.join(
|
||||
repodir, manifest_xml.MANIFEST_FILE_NAME
|
||||
)
|
||||
os.mkdir(repodir)
|
||||
os.mkdir(manifest_dir)
|
||||
manifest = manifest_xml.XmlManifest(repodir, manifest_file)
|
||||
proj = project.ManifestProject(
|
||||
manifest,
|
||||
"test/manifest",
|
||||
os.path.join(tempdir, ".git"),
|
||||
tempdir,
|
||||
)
|
||||
proj.revisionExpr = sha
|
||||
proj.upstream = None
|
||||
proj._CheckForImmutableRevision = mock.MagicMock(return_value=False)
|
||||
|
||||
mock_remote = mock.MagicMock()
|
||||
mock_remote.name = "origin"
|
||||
|
||||
def _to_local(r: str) -> str:
|
||||
if r.startswith("refs/heads/"):
|
||||
return "refs/remotes/origin/" + r[11:]
|
||||
return r
|
||||
|
||||
mock_remote.ToLocal.side_effect = _to_local
|
||||
mock_remote.PreConnectFetch.return_value = True
|
||||
proj.GetRemote = mock.MagicMock(return_value=mock_remote)
|
||||
|
||||
with mock.patch("project.GitCommand") as mock_git_cmd:
|
||||
mock_cmd_instance = mock.MagicMock()
|
||||
mock_cmd_instance.Wait.return_value = 0
|
||||
mock_git_cmd.return_value = mock_cmd_instance
|
||||
|
||||
res = proj._RemoteFetch(current_branch_only=True)
|
||||
|
||||
self.assertTrue(res)
|
||||
mock_git_cmd.assert_called_once()
|
||||
cmd_args = mock_git_cmd.call_args[0][1]
|
||||
self.assertIn("+refs/heads/*:refs/remotes/origin/*", cmd_args)
|
||||
|
||||
def test_remote_fetch_sha1_none_manifest_default(self) -> None:
|
||||
"""Test _GetUpstreamFallback when manifest.default is None."""
|
||||
sha = "4f8a3c0000000000000000000000000000000000"
|
||||
with utils_for_test.TempGitTree() as tempdir:
|
||||
proj = self._get_project(tempdir, revisionExpr=sha)
|
||||
proj.dest_branch = None
|
||||
proj.manifest.default = None
|
||||
self.assertIsNone(proj._GetUpstreamFallback())
|
||||
|
||||
|
||||
class GetEnvVarsTests(unittest.TestCase):
|
||||
"""Tests for GetEnvVars project environment variable generation."""
|
||||
|
||||
Reference in New Issue
Block a user