diff options
author | Albert Akmukhametov <arakmukhametov@salutedevices.com> | 2025-02-17 17:04:42 +0300 |
---|---|---|
committer | LUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2025-03-13 09:12:45 -0700 |
commit | 4b94e773efd36754f6c8649ad55b90d19a61107f (patch) | |
tree | 440f35763639becf735b12a770b1783dfc6700ba /project.py | |
parent | fc901b92bbcde2c16cd557322041abf958297665 (diff) | |
download | git-repo-4b94e773efd36754f6c8649ad55b90d19a61107f.tar.gz |
Sync: Fix full submodule sync while shallow specifiedv2.53
Git allows to clone submodules as shallow clone [1]. On the other
hand, when repo synchronize a projcet with submodules inside, it
ignores the shallow parameter.
When a project contains submodules, project.py parses the .gitmodules
file for URL and path. This parsing does not consider the shallow
option. Consequently, this parameter is not propgated to newly
created Project instance for that submodule.
[1] https://git-scm.com/docs/gitmodules#Documentation/gitmodules.txt-submoduleltnamegtshallow
Change-Id: I54fc9c69ae1b8e3cda2801202e3f0c7693b718d2
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/454261
Tested-by: Albert Akmukhametov <alb.02057@gmail.com>
Commit-Queue: Albert Akmukhametov <alb.02057@gmail.com>
Reviewed-by: Josip Sokcevic <sokcevic@chromium.org>
Reviewed-by: Никита Сказкоподателев (Nask) <skazkopodatelev@gmail.com>
Diffstat (limited to 'project.py')
-rw-r--r-- | project.py | 28 |
1 files changed, 20 insertions, 8 deletions
@@ -2197,24 +2197,27 @@ class Project: | |||
2197 | 2197 | ||
2198 | def get_submodules(gitdir, rev): | 2198 | def get_submodules(gitdir, rev): |
2199 | # Parse .gitmodules for submodule sub_paths and sub_urls. | 2199 | # Parse .gitmodules for submodule sub_paths and sub_urls. |
2200 | sub_paths, sub_urls = parse_gitmodules(gitdir, rev) | 2200 | sub_paths, sub_urls, sub_shallows = parse_gitmodules(gitdir, rev) |
2201 | if not sub_paths: | 2201 | if not sub_paths: |
2202 | return [] | 2202 | return [] |
2203 | # Run `git ls-tree` to read SHAs of submodule object, which happen | 2203 | # Run `git ls-tree` to read SHAs of submodule object, which happen |
2204 | # to be revision of submodule repository. | 2204 | # to be revision of submodule repository. |
2205 | sub_revs = git_ls_tree(gitdir, rev, sub_paths) | 2205 | sub_revs = git_ls_tree(gitdir, rev, sub_paths) |
2206 | submodules = [] | 2206 | submodules = [] |
2207 | for sub_path, sub_url in zip(sub_paths, sub_urls): | 2207 | for sub_path, sub_url, sub_shallow in zip( |
2208 | sub_paths, sub_urls, sub_shallows | ||
2209 | ): | ||
2208 | try: | 2210 | try: |
2209 | sub_rev = sub_revs[sub_path] | 2211 | sub_rev = sub_revs[sub_path] |
2210 | except KeyError: | 2212 | except KeyError: |
2211 | # Ignore non-exist submodules. | 2213 | # Ignore non-exist submodules. |
2212 | continue | 2214 | continue |
2213 | submodules.append((sub_rev, sub_path, sub_url)) | 2215 | submodules.append((sub_rev, sub_path, sub_url, sub_shallow)) |
2214 | return submodules | 2216 | return submodules |
2215 | 2217 | ||
2216 | re_path = re.compile(r"^submodule\.(.+)\.path=(.*)$") | 2218 | re_path = re.compile(r"^submodule\.(.+)\.path=(.*)$") |
2217 | re_url = re.compile(r"^submodule\.(.+)\.url=(.*)$") | 2219 | re_url = re.compile(r"^submodule\.(.+)\.url=(.*)$") |
2220 | re_shallow = re.compile(r"^submodule\.(.+)\.shallow=(.*)$") | ||
2218 | 2221 | ||
2219 | def parse_gitmodules(gitdir, rev): | 2222 | def parse_gitmodules(gitdir, rev): |
2220 | cmd = ["cat-file", "blob", "%s:.gitmodules" % rev] | 2223 | cmd = ["cat-file", "blob", "%s:.gitmodules" % rev] |
@@ -2228,9 +2231,9 @@ class Project: | |||
2228 | gitdir=gitdir, | 2231 | gitdir=gitdir, |
2229 | ) | 2232 | ) |
2230 | except GitError: | 2233 | except GitError: |
2231 | return [], [] | 2234 | return [], [], [] |
2232 | if p.Wait() != 0: | 2235 | if p.Wait() != 0: |
2233 | return [], [] | 2236 | return [], [], [] |
2234 | 2237 | ||
2235 | gitmodules_lines = [] | 2238 | gitmodules_lines = [] |
2236 | fd, temp_gitmodules_path = tempfile.mkstemp() | 2239 | fd, temp_gitmodules_path = tempfile.mkstemp() |
@@ -2247,16 +2250,17 @@ class Project: | |||
2247 | gitdir=gitdir, | 2250 | gitdir=gitdir, |
2248 | ) | 2251 | ) |
2249 | if p.Wait() != 0: | 2252 | if p.Wait() != 0: |
2250 | return [], [] | 2253 | return [], [], [] |
2251 | gitmodules_lines = p.stdout.split("\n") | 2254 | gitmodules_lines = p.stdout.split("\n") |
2252 | except GitError: | 2255 | except GitError: |
2253 | return [], [] | 2256 | return [], [], [] |
2254 | finally: | 2257 | finally: |
2255 | platform_utils.remove(temp_gitmodules_path) | 2258 | platform_utils.remove(temp_gitmodules_path) |
2256 | 2259 | ||
2257 | names = set() | 2260 | names = set() |
2258 | paths = {} | 2261 | paths = {} |
2259 | urls = {} | 2262 | urls = {} |
2263 | shallows = {} | ||
2260 | for line in gitmodules_lines: | 2264 | for line in gitmodules_lines: |
2261 | if not line: | 2265 | if not line: |
2262 | continue | 2266 | continue |
@@ -2270,10 +2274,16 @@ class Project: | |||
2270 | names.add(m.group(1)) | 2274 | names.add(m.group(1)) |
2271 | urls[m.group(1)] = m.group(2) | 2275 | urls[m.group(1)] = m.group(2) |
2272 | continue | 2276 | continue |
2277 | m = re_shallow.match(line) | ||
2278 | if m: | ||
2279 | names.add(m.group(1)) | ||
2280 | shallows[m.group(1)] = m.group(2) | ||
2281 | continue | ||
2273 | names = sorted(names) | 2282 | names = sorted(names) |
2274 | return ( | 2283 | return ( |
2275 | [paths.get(name, "") for name in names], | 2284 | [paths.get(name, "") for name in names], |
2276 | [urls.get(name, "") for name in names], | 2285 | [urls.get(name, "") for name in names], |
2286 | [shallows.get(name, "") for name in names], | ||
2277 | ) | 2287 | ) |
2278 | 2288 | ||
2279 | def git_ls_tree(gitdir, rev, paths): | 2289 | def git_ls_tree(gitdir, rev, paths): |
@@ -2314,7 +2324,7 @@ class Project: | |||
2314 | # If git repo does not exist yet, querying its submodules will | 2324 | # If git repo does not exist yet, querying its submodules will |
2315 | # mess up its states; so return here. | 2325 | # mess up its states; so return here. |
2316 | return result | 2326 | return result |
2317 | for rev, path, url in self._GetSubmodules(): | 2327 | for rev, path, url, shallow in self._GetSubmodules(): |
2318 | name = self.manifest.GetSubprojectName(self, path) | 2328 | name = self.manifest.GetSubprojectName(self, path) |
2319 | ( | 2329 | ( |
2320 | relpath, | 2330 | relpath, |
@@ -2336,6 +2346,7 @@ class Project: | |||
2336 | review=self.remote.review, | 2346 | review=self.remote.review, |
2337 | revision=self.remote.revision, | 2347 | revision=self.remote.revision, |
2338 | ) | 2348 | ) |
2349 | clone_depth = 1 if shallow.lower() == "true" else None | ||
2339 | subproject = Project( | 2350 | subproject = Project( |
2340 | manifest=self.manifest, | 2351 | manifest=self.manifest, |
2341 | name=name, | 2352 | name=name, |
@@ -2352,6 +2363,7 @@ class Project: | |||
2352 | sync_s=self.sync_s, | 2363 | sync_s=self.sync_s, |
2353 | sync_tags=self.sync_tags, | 2364 | sync_tags=self.sync_tags, |
2354 | parent=self, | 2365 | parent=self, |
2366 | clone_depth=clone_depth, | ||
2355 | is_derived=True, | 2367 | is_derived=True, |
2356 | ) | 2368 | ) |
2357 | result.append(subproject) | 2369 | result.append(subproject) |