summaryrefslogtreecommitdiffstats
path: root/tests/test_command.py
diff options
context:
space:
mode:
authorJosef Malmström <josef.malmstrom@arm.com>2026-05-06 16:19:52 +0200
committergerrit-scoped@luci-project-accounts.iam.gserviceaccount.com <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com>2026-05-20 06:05:57 -0700
commit1b4e7a04be7b49d8c0c5e161d36f209bca4b6498 (patch)
treee806e49daa47688240c75f6d5fdb20cc97cec509 /tests/test_command.py
parenta94c9e2b521096ff961da1bc6daf97d74add121c (diff)
downloadgit-repo-1b4e7a04be7b49d8c0c5e161d36f209bca4b6498.tar.gz
Fix submodules not synced for repeated repo
If I check out e.g. multiple branches of the same repo in one manifest, only the submodules of one checkout are synced. Fix this by adding the relative path of the checkout as a key to the mapping of derived projects, preventing overwrite. The fix was originally proposed here: https://issues.gerritcodereview.com/issues/40013218 Bug: 40013218 Change-Id: Ia86518ccf2c0af7bd7e4daf8d703a55b7e10ba52 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/581062 Reviewed-by: Mike Frysinger <vapier@google.com> Reviewed-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Josef Malmstrom <Josef.Malmstrom@arm.com> Tested-by: Josef Malmstrom <Josef.Malmstrom@arm.com>
Diffstat (limited to 'tests/test_command.py')
-rw-r--r--tests/test_command.py88
1 files changed, 88 insertions, 0 deletions
diff --git a/tests/test_command.py b/tests/test_command.py
new file mode 100644
index 000000000..bd2a47f71
--- /dev/null
+++ b/tests/test_command.py
@@ -0,0 +1,88 @@
1# Copyright (C) 2026 The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7# http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14
15"""Unittests for the command.py module."""
16
17from command import Command
18
19
20class FakeProject:
21 """Minimal project double for Command.GetProjects tests."""
22
23 def __init__(
24 self,
25 name,
26 relpath,
27 *,
28 gitdir=None,
29 derived_subprojects=None,
30 sync_s=False,
31 ):
32 self.name = name
33 self.relpath = relpath
34 self.gitdir = gitdir or f"/git/{relpath}"
35 self.sync_s = sync_s
36 self.Exists = True
37 self._derived_subprojects = derived_subprojects or []
38
39 def GetDerivedSubprojects(self):
40 return list(self._derived_subprojects)
41
42 def MatchesGroups(self, _groups):
43 return True
44
45 def RelPath(self, local=True):
46 return self.relpath
47
48
49class FakeManifest:
50 """Minimal manifest double for Command.GetProjects tests."""
51
52 def __init__(self, projects):
53 self.projects = projects
54
55 def GetManifestGroupsStr(self):
56 return "default"
57
58
59def test_get_projects_keeps_derived_subprojects_for_repeated_repo():
60 """Derived subprojects are keyed by checkout path, not repo identity."""
61 submodule_a = FakeProject(
62 "submodule",
63 "src/one/submodule",
64 gitdir="/shared/modules/submodule.git",
65 )
66 submodule_b = FakeProject(
67 "submodule",
68 "src/two/submodule",
69 gitdir="/shared/modules/submodule.git",
70 )
71 project_a = FakeProject(
72 "project",
73 "src/one",
74 derived_subprojects=[submodule_a],
75 sync_s=True,
76 )
77 project_b = FakeProject(
78 "project",
79 "src/two",
80 derived_subprojects=[submodule_b],
81 sync_s=True,
82 )
83 manifest = FakeManifest([project_a, project_b])
84 cmd = Command(manifest=manifest)
85
86 projects = cmd.GetProjects([])
87
88 assert set(projects) == {project_a, project_b, submodule_a, submodule_b}