sync: keep smart sync override with -l

Splitting a sync into `repo sync -n` followed by `repo sync -l` should
end up in the same state as a single `repo sync`. With smart sync it
does not always: -n fetches the revisions pinned by the smart sync
manifest and saves it as smart_sync_override.xml, but the following -l
deletes that override and checks out ToT instead, unless the manifest
sets sync-smartsync="true". So `repo sync -s -n` + `repo sync -l` lands
on ToT, while `repo sync -s` lands on the pinned revisions.

Without an explicit -s or -t, -l does not contact the manifest server,
so it cannot choose new pins itself; the only consistent choice is to
keep the override the previous -n left behind. Do that regardless of
the manifest default.

Syncs that choose a manifest themselves still replace or remove the
override as before: any sync without -l, and -l combined with -s, -t,
-m, --superproject-revision or --no-smart-sync. Smart sync stays
non-sticky for regular syncs, and `repo sync -l --no-smart-sync` still
discards the override to check out ToT.

Bug: 569927750
Change-Id: Id06ff88e9f3183fae32e993e86630fc3e8de71a1
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/640965
Commit-Queue: Rahul Yadav <yadavrah@google.com>
Tested-by: Rahul Yadav <yadavrah@google.com>
Reviewed-by: Gavin Mak <gavinmak@google.com>
This commit is contained in:
Rahul Yadav authored and gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com committed 2026-10-12 02:14:30 -07:00
1 parent beda65323e
commit 178b66ee3e
3 files changed
+51 -41

No files matched your search

+31 -26
View File
@@ -1774,25 +1774,34 @@ class SyncCommand(unittest.TestCase):
return override_path, setup, reload, update_mps
def test_smart_sync_override_reused_offline(self) -> None:
"""Ensure -l reuses an onboarded client's smart sync manifest."""
for mp_update in (True, False):
with self.subTest(mp_update=mp_update):
self.manifest.default.sync_smartsync = True
self.opt.smart_sync = None
self.opt.local_only = True
self.opt.mp_update = mp_update
path, setup, reload, update_mps = (
self._ExecuteWithSmartSyncOverride()
)
setup.assert_not_called()
reload.assert_called_once_with(
"smart_sync_override.xml", self.manifest
)
self.assertTrue(os.path.isfile(path))
if mp_update:
self.assertEqual(
update_mps.call_args[0][2], "smart_sync_override.xml"
"""Ensure -l reuses an existing smart sync manifest.
This applies whether the override came from the manifest's
sync-smartsync default or from an explicit -s, so that `sync -n`
followed by `sync -l` matches a single sync.
"""
for sync_smartsync in (True, False):
for mp_update in (True, False):
with self.subTest(
sync_smartsync=sync_smartsync, mp_update=mp_update
):
self.manifest.default.sync_smartsync = sync_smartsync
self.opt.smart_sync = None
self.opt.local_only = True
self.opt.mp_update = mp_update
path, setup, reload, update_mps = (
self._ExecuteWithSmartSyncOverride()
)
setup.assert_not_called()
reload.assert_called_once_with(
"smart_sync_override.xml", self.manifest
)
self.assertTrue(os.path.isfile(path))
if mp_update:
self.assertEqual(
update_mps.call_args[0][2],
"smart_sync_override.xml",
)
def test_no_manifest_update_keeps_default_smart_sync(self) -> None:
"""Ensure --nmu still runs the manifest-driven default smart sync."""
@@ -1821,15 +1830,11 @@ class SyncCommand(unittest.TestCase):
self.assertFalse(os.path.isfile(path))
def test_smart_sync_override_removed_offline(self) -> None:
"""Ensure -l still drops the override when reuse does not apply."""
cases = (
("--no-smart-sync", False, True),
("manifest without sync-smartsync", None, False),
)
for name, smart_sync, sync_smartsync in cases:
with self.subTest(name):
"""Ensure -l --no-smart-sync still drops the override."""
for sync_smartsync in (True, False):
with self.subTest(sync_smartsync=sync_smartsync):
self.manifest.default.sync_smartsync = sync_smartsync
self.opt.smart_sync = smart_sync
self.opt.smart_sync = False
self.opt.local_only = True
path, setup, reload, _ = self._ExecuteWithSmartSyncOverride()
setup.assert_not_called()