summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Schulte <matsch@google.com>2023-11-30 11:00:16 -0800
committerLUCI <gerrit-scoped@luci-project-accounts.iam.gserviceaccount.com>2023-11-30 22:36:41 +0000
commit0dd0a830b055e177a713bbc81fc7ecdda1605643 (patch)
treeec8edb979c4ef993e21eb2418686a4e8be6ff17a
parent9f0ef5d926b29cabf8509be1b777c24c192c5e21 (diff)
downloadgit-repo-0dd0a830b055e177a713bbc81fc7ecdda1605643.tar.gz
sync: Fix partial sync false positive
In the case of a project being removed from the manifest, and in the path in which the project used to exist, and symlink is place to another project repo will start to warn about partial syncs when a partial sync did not occur. Repro steps: 1) Create a manifest with two projects. Project a -> a/ and project b -> b/ 2) Run `repo sync` 3) Remove project b from the manifest. 4) Use `link` in the manifest to link all of Project a to b/ Bug: 314161804 Change-Id: I4a4ac4f70a7038bc7e0c4e0e51ae9fc942411a34 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/395640 Reviewed-by: Gavin Mak <gavinmak@google.com> Tested-by: Matt Schulte <matsch@google.com> Commit-Queue: Gavin Mak <gavinmak@google.com>
-rw-r--r--subcmds/sync.py2
-rw-r--r--tests/test_subcmds_sync.py38
2 files changed, 39 insertions, 1 deletions
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 02c1d3ae..b7236629 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -2011,7 +2011,7 @@ class LocalSyncState:
2011 delete = set() 2011 delete = set()
2012 for path in self._state: 2012 for path in self._state:
2013 gitdir = os.path.join(self._manifest.topdir, path, ".git") 2013 gitdir = os.path.join(self._manifest.topdir, path, ".git")
2014 if not os.path.exists(gitdir): 2014 if not os.path.exists(gitdir) or os.path.islink(gitdir):
2015 delete.add(path) 2015 delete.add(path)
2016 if not delete: 2016 if not delete:
2017 return 2017 return
diff --git a/tests/test_subcmds_sync.py b/tests/test_subcmds_sync.py
index 71e40489..af6bbef7 100644
--- a/tests/test_subcmds_sync.py
+++ b/tests/test_subcmds_sync.py
@@ -265,6 +265,44 @@ class LocalSyncState(unittest.TestCase):
265 self.assertIsNone(self.state.GetFetchTime(projA)) 265 self.assertIsNone(self.state.GetFetchTime(projA))
266 self.assertEqual(self.state.GetFetchTime(projB), 7) 266 self.assertEqual(self.state.GetFetchTime(projB), 7)
267 267
268 def test_prune_removed_and_symlinked_projects(self):
269 """Removed projects that still exists on disk as symlink are pruned."""
270 with open(self.state._path, "w") as f:
271 f.write(
272 """
273 {
274 "projA": {
275 "last_fetch": 5
276 },
277 "projB": {
278 "last_fetch": 7
279 }
280 }
281 """
282 )
283
284 def mock_exists(path):
285 return True
286
287 def mock_islink(path):
288 if "projB" in path:
289 return True
290 return False
291
292 projA = mock.MagicMock(relpath="projA")
293 projB = mock.MagicMock(relpath="projB")
294 self.state = self._new_state()
295 self.assertEqual(self.state.GetFetchTime(projA), 5)
296 self.assertEqual(self.state.GetFetchTime(projB), 7)
297 with mock.patch("os.path.exists", side_effect=mock_exists):
298 with mock.patch("os.path.islink", side_effect=mock_islink):
299 self.state.PruneRemovedProjects()
300 self.assertIsNone(self.state.GetFetchTime(projB))
301
302 self.state = self._new_state()
303 self.assertIsNone(self.state.GetFetchTime(projB))
304 self.assertEqual(self.state.GetFetchTime(projA), 5)
305
268 306
269class GetPreciousObjectsState(unittest.TestCase): 307class GetPreciousObjectsState(unittest.TestCase):
270 """Tests for _GetPreciousObjectsState.""" 308 """Tests for _GetPreciousObjectsState."""