mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-10-22 05:08:25 +00:00
sync: Support manifest-driven default smart sync
Add support for enabling smart sync by default via the sync-smartsync="true" attribute on the manifest <default> element. When sync-smartsync is set to true in the manifest defaults: - Plain `repo sync` triggers Smart Sync automatically. - If that implicit Smart Sync fails (manifest server unreachable, or the returned manifest cannot be parsed), repo silently falls back to a regular ToT sync. The reason is logged with --verbose. - `--no-smart-sync` CLI flag overrides the manifest default and syncs to ToT. - Passing explicit `-s` / `--smart-sync` forces Smart Sync as before, and its failures are still fatal. - `-t`, `--smart-tag`, `-m`, `--manifest-name`, and `--superproject-revision` disable the default smart sync. - `-l` / `--local-only` and `--no-manifest-update` skip the manifest server and reuse the existing smart_sync_override.xml, if any. Update docs, completion, regenerate man pages, and add tests for XML parsing, serialization, CLI option resolution, and the fallback and reuse paths. Bug: 545137090 Change-Id: If75569c58dd525d170e9801e70ccbf02206a52f2 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/617641 Tested-by: Rahul Yadav <yadavrah@google.com> Commit-Queue: Rahul Yadav <yadavrah@google.com> Reviewed-by: Gavin Mak <gavinmak@google.com>
This commit is contained in:
1 parent
5d4149f32e
commit
d53a4278f5
9 files changed
+527
-33
No files matched your search
+87
-8
@@ -58,6 +58,7 @@ from command import DEFAULT_LOCAL_JOBS
|
||||
from command import MirrorSafeCommand
|
||||
from command import WORKER_BATCH_SIZE
|
||||
from error import GitError
|
||||
from error import ManifestParseError
|
||||
from error import RepoChangedException
|
||||
from error import RepoError
|
||||
from error import RepoExitError
|
||||
@@ -764,9 +765,16 @@ later is required to fix a server side protocol bug.
|
||||
"-s",
|
||||
"--smart-sync",
|
||||
action="store_true",
|
||||
default=None,
|
||||
help="smart sync using manifest from the latest known good "
|
||||
"build",
|
||||
)
|
||||
p.add_option(
|
||||
"--no-smart-sync",
|
||||
dest="smart_sync",
|
||||
action="store_false",
|
||||
help="disable smart sync and sync to ToT instead",
|
||||
)
|
||||
p.add_option(
|
||||
"-t",
|
||||
"--smart-tag",
|
||||
@@ -2249,10 +2257,6 @@ later is required to fix a server side protocol bug.
|
||||
if opt.manifest_name and opt.smart_tag:
|
||||
self.OptionParser.error("cannot combine -m and -t")
|
||||
if opt.manifest_server_username or opt.manifest_server_password:
|
||||
if not (opt.smart_sync or opt.smart_tag):
|
||||
self.OptionParser.error(
|
||||
"-u and -p may only be combined with -s or -t"
|
||||
)
|
||||
if None in [
|
||||
opt.manifest_server_username,
|
||||
opt.manifest_server_password,
|
||||
@@ -2413,6 +2417,34 @@ later is required to fix a server side protocol bug.
|
||||
"failed to sync manifest project", aggregate_errors=[e]
|
||||
)
|
||||
|
||||
def _ResolveSmartSyncOption(
|
||||
self, opt: optparse.Values, manifest: XmlManifest
|
||||
) -> bool:
|
||||
"""Resolve opt.smart_sync from the CLI flags and manifest default.
|
||||
|
||||
Returns:
|
||||
True if smart_sync was enabled implicitly by the manifest default,
|
||||
False otherwise.
|
||||
"""
|
||||
implicit = (
|
||||
opt.smart_sync is None
|
||||
and not opt.smart_tag
|
||||
and not opt.manifest_name
|
||||
and not opt.superproject_revision
|
||||
and not opt.local_only
|
||||
and opt.mp_update
|
||||
and getattr(manifest.default, "sync_smartsync", False) is True
|
||||
)
|
||||
if opt.smart_sync is None:
|
||||
opt.smart_sync = implicit
|
||||
|
||||
if (
|
||||
opt.manifest_server_username or opt.manifest_server_password
|
||||
) and not (opt.smart_sync or opt.smart_tag):
|
||||
raise SmartSyncError("-u and -p may only be combined with -s or -t")
|
||||
|
||||
return implicit
|
||||
|
||||
def _ExecuteHelper(self, opt, args, errors):
|
||||
manifest = self.outer_manifest
|
||||
if not opt.outer_manifest:
|
||||
@@ -2427,11 +2459,58 @@ later is required to fix a server side protocol bug.
|
||||
if opt.clone_bundle is None:
|
||||
opt.clone_bundle = manifest.CloneBundle
|
||||
|
||||
# An onboarded client run with -l or --no-manifest-update keeps the
|
||||
# smart sync manifest it last synced to instead of contacting the
|
||||
# manifest server. Computed before _ResolveSmartSyncOption, which
|
||||
# makes an unset opt.smart_sync indistinguishable from --no-smart-sync.
|
||||
reuse_smart_sync_override = (
|
||||
(opt.local_only or not opt.mp_update)
|
||||
and opt.smart_sync is None
|
||||
and not opt.smart_tag
|
||||
and not opt.manifest_name
|
||||
and not opt.superproject_revision
|
||||
and getattr(manifest.default, "sync_smartsync", False) is True
|
||||
and os.path.isfile(smart_sync_manifest_path)
|
||||
)
|
||||
|
||||
implicit_smart_sync = self._ResolveSmartSyncOption(opt, manifest)
|
||||
|
||||
if opt.smart_sync or opt.smart_tag:
|
||||
manifest_name = self._SmartSyncSetup(
|
||||
opt, smart_sync_manifest_path, manifest
|
||||
)
|
||||
else:
|
||||
try:
|
||||
manifest_name = self._SmartSyncSetup(
|
||||
opt, smart_sync_manifest_path, manifest
|
||||
)
|
||||
except (SmartSyncError, ManifestParseError) as e:
|
||||
if not implicit_smart_sync:
|
||||
raise
|
||||
# The user did not ask for a smart sync, so failing to get a
|
||||
# usable manifest from the server should not fail the sync.
|
||||
# Fall back to a regular ToT sync instead.
|
||||
opt.smart_sync = False
|
||||
# Override() records the override before parsing it, so an
|
||||
# unparsable manifest would otherwise leave the client pinned
|
||||
# to a file it cannot load.
|
||||
manifest.ClearOverride()
|
||||
if opt.verbose:
|
||||
logger.warning(
|
||||
"warning: smart sync failed; falling back to ToT: %s", e
|
||||
)
|
||||
elif reuse_smart_sync_override:
|
||||
manifest_name = os.path.basename(smart_sync_manifest_path)
|
||||
try:
|
||||
self._ReloadManifest(manifest_name, manifest)
|
||||
except ManifestParseError as e:
|
||||
reuse_smart_sync_override = False
|
||||
manifest_name = None
|
||||
manifest.ClearOverride()
|
||||
if opt.verbose:
|
||||
logger.warning(
|
||||
"warning: failed to load existing smart sync manifest; "
|
||||
"falling back to ToT: %s",
|
||||
e,
|
||||
)
|
||||
|
||||
if not (opt.smart_sync or opt.smart_tag or reuse_smart_sync_override):
|
||||
if os.path.isfile(smart_sync_manifest_path):
|
||||
try:
|
||||
platform_utils.remove(smart_sync_manifest_path)
|
||||
|
||||
Reference in new issue
Block a user