diff options
| author | Gavin Mak <gavinmak@google.com> | 2026-08-25 08:57:34 -0700 |
|---|---|---|
| committer | gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com> | 2026-09-21 13:40:01 -0700 |
| commit | f6f5946422097f2559cf3bc39a69d5fddc838ab8 (patch) | |
| tree | 907c50c76bf1a0fc0d5d755913947c154ed09fe0 /tests | |
| parent | 6321b26685ff9bdf5858e574dc4967761990ce5b (diff) | |
| download | git-repo-f6f5946422097f2559cf3bc39a69d5fddc838ab8.tar.gz | |
project: avoid unnecessary sync revision enumeration
Skip the detached-history walk when its count will not be printed, ask
rev-list --count for upstream gain, and cap the published-but-unmerged
existence probe at one commit. These preserve the decisions while
reducing traversal and output work.
Bug: 553599402
Change-Id: I30f769c9aa5269428ece15ffcb45c50993d7c4b8
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/634004
Commit-Queue: Gavin Mak <gavinmak@google.com>
Tested-by: Gavin Mak <gavinmak@google.com>
Reviewed-by: Brian Gan <brgan@google.com>
Diffstat (limited to 'tests')
| -rw-r--r-- | tests/test_project.py | 97 |
1 files changed, 95 insertions, 2 deletions
diff --git a/tests/test_project.py b/tests/test_project.py index ab20105fd..d02dabf3b 100644 --- a/tests/test_project.py +++ b/tests/test_project.py | |||
| @@ -2248,6 +2248,97 @@ class StatelessSyncTests(unittest.TestCase): | |||
| 2248 | ) | 2248 | ) |
| 2249 | proj._CopyAndLinkFiles.assert_called_once_with() | 2249 | proj._CopyAndLinkFiles.assert_called_once_with() |
| 2250 | 2250 | ||
| 2251 | def test_sync_local_half_skips_unused_detached_history_walk(self) -> None: | ||
| 2252 | """Non-verbose detached sync does not enumerate discarded commits.""" | ||
| 2253 | with utils_for_test.TempGitTree() as tempdir: | ||
| 2254 | proj = self._get_project(tempdir) | ||
| 2255 | proj._InitWorkTree = mock.MagicMock() | ||
| 2256 | proj.CleanPublishedCache = mock.MagicMock() | ||
| 2257 | proj.GetRevisionId = mock.MagicMock(return_value="new") | ||
| 2258 | proj._Checkout = mock.MagicMock() | ||
| 2259 | proj._CopyAndLinkFiles = mock.MagicMock() | ||
| 2260 | proj.IsRebaseInProgress = mock.MagicMock(return_value=False) | ||
| 2261 | proj.IsCherryPickInProgress = mock.MagicMock(return_value=False) | ||
| 2262 | proj._revlist = mock.MagicMock() | ||
| 2263 | proj.bare_ref = mock.MagicMock() | ||
| 2264 | proj.bare_ref.all = {"HEAD": "old"} | ||
| 2265 | proj.bare_ref.head = "old" | ||
| 2266 | proj.work_git = mock.MagicMock() | ||
| 2267 | proj.work_git.GetHead.return_value = "old" | ||
| 2268 | |||
| 2269 | syncbuf = project.SyncBuffer(proj.config) | ||
| 2270 | proj.Sync_LocalHalf(syncbuf, verbose=False) | ||
| 2271 | |||
| 2272 | proj._revlist.assert_not_called() | ||
| 2273 | proj._Checkout.assert_called_once_with( | ||
| 2274 | "new", force_checkout=False, quiet=True | ||
| 2275 | ) | ||
| 2276 | |||
| 2277 | def test_sync_local_half_verbose_detached_uses_count(self) -> None: | ||
| 2278 | """Verbose detached sync queries commit count with --count.""" | ||
| 2279 | with utils_for_test.TempGitTree() as tempdir: | ||
| 2280 | proj = self._get_project(tempdir) | ||
| 2281 | proj._InitWorkTree = mock.MagicMock() | ||
| 2282 | proj.CleanPublishedCache = mock.MagicMock() | ||
| 2283 | proj.GetRevisionId = mock.MagicMock(return_value="new") | ||
| 2284 | proj._Checkout = mock.MagicMock() | ||
| 2285 | proj._CopyAndLinkFiles = mock.MagicMock() | ||
| 2286 | proj.IsRebaseInProgress = mock.MagicMock(return_value=False) | ||
| 2287 | proj.IsCherryPickInProgress = mock.MagicMock(return_value=False) | ||
| 2288 | proj._revlist = mock.MagicMock(return_value=["3"]) | ||
| 2289 | proj.bare_ref = mock.MagicMock() | ||
| 2290 | proj.bare_ref.all = {"HEAD": "old"} | ||
| 2291 | proj.bare_ref.head = "old" | ||
| 2292 | proj.work_git = mock.MagicMock() | ||
| 2293 | proj.work_git.GetHead.return_value = "old" | ||
| 2294 | |||
| 2295 | syncbuf = mock.MagicMock() | ||
| 2296 | syncbuf.detach_head = False | ||
| 2297 | proj.Sync_LocalHalf(syncbuf, verbose=True) | ||
| 2298 | |||
| 2299 | proj._revlist.assert_called_once_with("--count", "^new", "HEAD") | ||
| 2300 | syncbuf.info.assert_called_once_with( | ||
| 2301 | proj, "discarding %d commits", 3 | ||
| 2302 | ) | ||
| 2303 | |||
| 2304 | def test_sync_local_half_uses_count_and_limit_for_published_branch( | ||
| 2305 | self, | ||
| 2306 | ) -> None: | ||
| 2307 | """Published sync uses --count for gain and -1 for probe.""" | ||
| 2308 | with utils_for_test.TempGitTree() as tempdir: | ||
| 2309 | proj = self._get_project(tempdir) | ||
| 2310 | proj._InitWorkTree = mock.MagicMock() | ||
| 2311 | proj.CleanPublishedCache = mock.MagicMock() | ||
| 2312 | proj.GetRevisionId = mock.MagicMock(return_value="new") | ||
| 2313 | proj._CopyAndLinkFiles = mock.MagicMock() | ||
| 2314 | proj.IsRebaseInProgress = mock.MagicMock(return_value=False) | ||
| 2315 | proj.IsCherryPickInProgress = mock.MagicMock(return_value=False) | ||
| 2316 | proj._revlist = mock.MagicMock(side_effect=[["2"], ["pub-sha"]]) | ||
| 2317 | proj.bare_ref = mock.MagicMock() | ||
| 2318 | proj.bare_ref.all = {"refs/heads/topic": "old"} | ||
| 2319 | proj.bare_ref.head = "refs/heads/topic" | ||
| 2320 | proj.work_git = mock.MagicMock() | ||
| 2321 | proj.work_git.GetHead.return_value = "refs/heads/topic" | ||
| 2322 | proj.work_git.merge_base.side_effect = project.GitError("diverged") | ||
| 2323 | branch = mock.MagicMock() | ||
| 2324 | branch.name = "topic" | ||
| 2325 | branch.LocalMerge = "refs/remotes/origin/main" | ||
| 2326 | proj.GetBranch = mock.MagicMock(return_value=branch) | ||
| 2327 | proj.WasPublished = mock.MagicMock(return_value="pub-sha") | ||
| 2328 | |||
| 2329 | syncbuf = mock.MagicMock() | ||
| 2330 | syncbuf.detach_head = False | ||
| 2331 | proj.Sync_LocalHalf(syncbuf, force_rebase=False) | ||
| 2332 | |||
| 2333 | self.assertEqual( | ||
| 2334 | proj._revlist.call_args_list, | ||
| 2335 | [ | ||
| 2336 | mock.call("--count", "^HEAD", "new"), | ||
| 2337 | mock.call("-1", "^new", "pub-sha"), | ||
| 2338 | ], | ||
| 2339 | ) | ||
| 2340 | syncbuf.fail.assert_called_once() | ||
| 2341 | |||
| 2251 | def test_sync_network_half_stateless_skips_if_stash(self): | 2342 | def test_sync_network_half_stateless_skips_if_stash(self): |
| 2252 | """Test stateless sync skips if stash exists.""" | 2343 | """Test stateless sync skips if stash exists.""" |
| 2253 | with utils_for_test.TempGitTree() as tempdir: | 2344 | with utils_for_test.TempGitTree() as tempdir: |
| @@ -3351,9 +3442,11 @@ class ReprojectCmdTests(unittest.TestCase): | |||
| 3351 | def _revlist(*args: Any, **kwargs: Any) -> List[str]: | 3442 | def _revlist(*args: Any, **kwargs: Any) -> List[str]: |
| 3352 | if kwargs.get("format"): | 3443 | if kwargs.get("format"): |
| 3353 | return list(local_changes) | 3444 | return list(local_changes) |
| 3354 | if args[0] == project.not_rev(project.HEAD): | 3445 | if project.not_rev(project.HEAD) in args: |
| 3446 | if "--count" in args: | ||
| 3447 | return [str(len(upstream_gain))] | ||
| 3355 | return list(upstream_gain) | 3448 | return list(upstream_gain) |
| 3356 | if args[1] == self.PUB_ID: | 3449 | if self.PUB_ID in args: |
| 3357 | return [self.PUB_ID] | 3450 | return [self.PUB_ID] |
| 3358 | return [] | 3451 | return [] |
| 3359 | 3452 | ||
