sync: Add CLI flag for globally disabling submodule fetch

A global setting for disabling fetching of submodules is useful
since this can currently otherwise only be done by modifying
the manifest, or by explicitly providing projects on command line.

Add this setting as --no-fetch-submodules to mirror the existing
--fetch-submodules.

Change-Id: Ic727c54f11a594aa52315751284b87138cf246bb
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/607641
Commit-Queue: Josef Malmstrom <Josef.Malmstrom@arm.com>
Reviewed-by: Gavin Mak <gavinmak@google.com>
Tested-by: Josef Malmstrom <Josef.Malmstrom@arm.com>
Reviewed-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
Josef Malmström
2026-07-13 12:50:52 +02:00
committed by gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com
parent 0398c6718e
commit 978adb7ea5
7 changed files with 83 additions and 8 deletions
+16 -4
View File
@@ -17,6 +17,7 @@ import multiprocessing
import optparse
import os
import re
from typing import TYPE_CHECKING
from error import InvalidProjectGroupsError
from error import NoSuchProjectError
@@ -25,6 +26,10 @@ from event_log import EventLog
import progress
if TYPE_CHECKING:
from project import Project
# Are we generating man-pages?
GENERATE_MANPAGES = os.environ.get("_REPO_GENERATE_MANPAGES_") == " indeed! "
@@ -375,7 +380,7 @@ class Command:
manifest=None,
groups="",
missing_ok=False,
submodules_ok=False,
submodules_ok=None,
all_manifests=False,
):
"""A list of projects that match the arguments.
@@ -385,7 +390,9 @@ class Command:
manifest: an XmlManifest, the manifest to use, or None for default.
groups: a string, the manifest groups in use.
missing_ok: a boolean, whether to allow missing projects.
submodules_ok: a boolean, whether to allow submodules.
submodules_ok: whether to allow submodules. True allows them for
all projects, False disallows them for all projects, and None
defers to each project's sync-s setting.
all_manifests: a boolean, if True then all manifests and
submanifests are used. If False, then only the local
(sub)manifest is used.
@@ -403,6 +410,11 @@ class Command:
all_projects_list = manifest.projects
result = []
def should_include_submodules(project: "Project") -> bool:
if submodules_ok is None:
return project.sync_s
return submodules_ok
if not groups:
groups = manifest.GetManifestGroupsStr()
groups = [x for x in re.split(r"[,\s]+", groups) if x]
@@ -410,7 +422,7 @@ class Command:
if not args:
derived_projects = {}
for project in all_projects_list:
if submodules_ok or project.sync_s:
if should_include_submodules(project):
derived_projects.update(
(p.RelPath(local=False), p)
for p in project.GetDerivedSubprojects()
@@ -452,7 +464,7 @@ class Command:
if (
project
and not project.Derived
and (submodules_ok or project.sync_s)
and should_include_submodules(project)
):
search_again = False
for subproject in project.GetDerivedSubprojects():
+1
View File
@@ -323,6 +323,7 @@ _repo() {
'(-u --manifest-server-username)'{-u,--manifest-server-username=}'[Username for manifest server]:username:' \
'(-p --manifest-server-password)'{-p,--manifest-server-password=}'[Password for manifest server]:password:' \
'--fetch-submodules[Fetch submodules]' \
'--no-fetch-submodules[Do not fetch submodules]' \
'--use-superproject[Use superproject]' \
'--no-use-superproject[Do not use superproject]' \
'--tags[Sync tags]' \
+3
View File
@@ -83,6 +83,9 @@ password to authenticate with the manifest server
\fB\-\-fetch\-submodules\fR
fetch submodules from server
.TP
\fB\-\-no\-fetch\-submodules\fR
don't fetch submodules from server
.TP
\fB\-\-use\-superproject\fR
use the manifest superproject to sync projects; implies \fB\-c\fR
.TP
+7 -3
View File
@@ -1,5 +1,5 @@
.\" DO NOT MODIFY THIS FILE! It was generated by help2man.
.TH REPO "1" "June 2026" "repo sync" "Repo Manual"
.TH REPO "1" "July 2026" "repo sync" "Repo Manual"
.SH NAME
repo \- repo sync - manual page for repo sync
.SH SYNOPSIS
@@ -83,6 +83,9 @@ password to authenticate with the manifest server
\fB\-\-fetch\-submodules\fR
fetch submodules from server
.TP
\fB\-\-no\-fetch\-submodules\fR
don't fetch submodules from server
.TP
\fB\-\-use\-superproject\fR
use the manifest superproject to sync projects; implies \fB\-c\fR
.TP
@@ -212,8 +215,9 @@ bootstrap a new Git repository from a resumeable bundle file on a content
delivery network. This may be necessary if there are problems with the local
Python HTTP client or proxy configuration, but the Git binary works.
.PP
The \fB\-\-fetch\-submodules\fR option enables fetching Git submodules of a project from
server.
The \fB\-\-fetch\-submodules\fR option enables fetching Git submodules of all projects
from the server. The \fB\-\-no\-fetch\-submodules\fR option disables fetching Git
submodules, even when a project has sync\-s="true" in the manifest.
.PP
The \fB\-c\fR/\-\-current\-branch option can be used to only fetch objects that are on the
branch specified by a project's revision.
+8 -1
View File
@@ -379,7 +379,8 @@ may be necessary if there are problems with the local Python
HTTP client or proxy configuration, but the Git binary works.
The --fetch-submodules option enables fetching Git submodules
of a project from server.
of all projects from the server. The --no-fetch-submodules option disables
fetching Git submodules, even when a project has sync-s="true" in the manifest.
The -c/--current-branch option can be used to only fetch objects that
are on the branch specified by a project's revision.
@@ -573,6 +574,12 @@ later is required to fix a server side protocol bug.
action="store_true",
help="fetch submodules from server",
)
p.add_option(
"--no-fetch-submodules",
dest="fetch_submodules",
action="store_false",
help="don't fetch submodules from server",
)
p.add_option(
"--use-superproject",
action="store_true",
+31
View File
@@ -14,6 +14,8 @@
"""Unittests for the command.py module."""
import pytest
from command import Command
@@ -86,3 +88,32 @@ def test_get_projects_keeps_derived_subprojects_for_repeated_repo():
projects = cmd.GetProjects([])
assert set(projects) == {project_a, project_b, submodule_a, submodule_b}
@pytest.mark.parametrize(
"submodules_ok, sync_s, includes_submodule",
[
(None, False, False),
(None, True, True),
(True, False, True),
(True, True, True),
(False, False, False),
(False, True, False),
],
)
def test_get_projects_submodule_override(
submodules_ok, sync_s, includes_submodule
):
"""The CLI override takes precedence over a project's sync-s setting."""
submodule = FakeProject("submodule", "project/submodule")
project = FakeProject(
"project",
"project",
derived_subprojects=[submodule],
sync_s=sync_s,
)
cmd = Command(manifest=FakeManifest([project]))
projects = cmd.GetProjects([], submodules_ok=submodules_ok)
assert (submodule in projects) is includes_submodule
+17
View File
@@ -30,6 +30,23 @@ from project import SyncNetworkHalfResult
from subcmds import sync
@pytest.mark.parametrize(
"cli_args, expected",
[
([], None),
(["--fetch-submodules"], True),
(["--no-fetch-submodules"], False),
],
)
def test_fetch_submodules_option(cli_args, expected):
"""The fetch-submodules flags preserve an unset manifest-driven state."""
cmd = sync.Sync()
opts, _ = cmd.OptionParser.parse_args(cli_args)
assert opts.fetch_submodules is expected
@pytest.mark.parametrize(
"use_superproject, cli_args, result",
[