mirror of
https://gerrit.googlesource.com/git-repo
synced 2026-11-13 15:57:35 +00:00
sync: trim preciousObjects work
Only set preciousObjects when objdir differs from gitdir, check actual objdir sharing in _GetPreciousObjectsState, and skip post-sync preciousObjects scans on unshared --use-local-gitdirs projects. Bug: 543101585 Change-Id: I5077aed128f22cf19f520c7866cfd62f0c2724be Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/652266 Tested-by: Gavin Mak <gavinmak@google.com> Commit-Queue: Gavin Mak <gavinmak@google.com> Reviewed-by: Brian Gan <brgan@google.com>
This commit is contained in:
1 parent
c85e5ff8a5
commit
c9cfb541aa
3 files changed
+60
-13
No files matched your search
+1
-1
@@ -4490,7 +4490,7 @@ class Project:
|
||||
if tmp_gitdir:
|
||||
platform_utils.rename(tmp_gitdir, self.gitdir)
|
||||
tmp_gitdir = None
|
||||
if not init_obj_dir:
|
||||
if not init_obj_dir and self.objdir != self.gitdir:
|
||||
# The project might be shared (obj_dir already initialized), but
|
||||
# such information is not available here. Instead of passing it,
|
||||
# set it as shared, and rely to be unset down the execution
|
||||
|
||||
+22
-12
@@ -1563,22 +1563,20 @@ later is required to fix a server side protocol bug.
|
||||
if len(projects) == 1:
|
||||
return False
|
||||
if len(projects) > 1:
|
||||
# Objects are potentially shared with another project.
|
||||
if project.UseAlternates:
|
||||
return False
|
||||
# Objects are shared when another project uses the same objdir.
|
||||
# See the logic in Project.Sync_NetworkHalf regarding UseAlternates.
|
||||
# - When False, shared projects share (via symlink)
|
||||
# .repo/project-objects/{PROJECT_NAME}.git as the one-and-only
|
||||
# objects directory. All objects are precious, since there is no
|
||||
# project with a complete set of refs.
|
||||
# - When False and projects share .repo/project-objects/{NAME}.git
|
||||
# as the one-and-only objects directory, all objects are precious
|
||||
# since no project has a complete set of refs. Projects with
|
||||
# distinct local .git directories (--use-local-gitdirs) do not
|
||||
# share objects even when their manifest names match.
|
||||
# - When True, shared projects share (via info/alternates)
|
||||
# .repo/project-objects/{PROJECT_NAME}.git as an alternate object
|
||||
# store, which is written only on the first clone of the project,
|
||||
# and is not written subsequently. (When Sync_NetworkHalf sees
|
||||
# that it exists, it makes sure that the alternates file points
|
||||
# there, and uses a project-local .git/objects directory for all
|
||||
# syncs going forward.
|
||||
# We do not support switching between the options. The environment
|
||||
# variable is present for testing and migration only.
|
||||
return not project.UseAlternates
|
||||
# and is not written subsequently.
|
||||
return sum(1 for p in projects if p.objdir == project.objdir) > 1
|
||||
|
||||
return False
|
||||
|
||||
@@ -1649,6 +1647,18 @@ later is required to fix a server side protocol bug.
|
||||
if not opt.auto_gc:
|
||||
# Just repair preciousObjects state, and return.
|
||||
for project in projects:
|
||||
if (
|
||||
project.manifest.UseLocalGitDirs is True
|
||||
and not project.parent
|
||||
and getattr(project, "gitdir", None) == project.objdir
|
||||
and len(
|
||||
project.manifest.GetProjectsWithName(
|
||||
project.name, all_manifests=True
|
||||
)
|
||||
)
|
||||
== 1
|
||||
):
|
||||
continue
|
||||
cls._SetPreciousObjectsState(project, opt)
|
||||
return
|
||||
|
||||
|
||||
@@ -1374,6 +1374,20 @@ class GetPreciousObjectsState(unittest.TestCase):
|
||||
self.cmd._GetPreciousObjectsState(self.project, self.opt)
|
||||
)
|
||||
|
||||
def test_duplicate_name_distinct_objdirs(self) -> None:
|
||||
"""Duplicate-name projects with distinct local objdirs aren't shared."""
|
||||
other = mock.MagicMock(
|
||||
use_git_worktrees=False, UseAlternates=False, objdir="b/.git"
|
||||
)
|
||||
self.project.objdir = "a/.git"
|
||||
self.project.manifest.GetProjectsWithName.return_value = [
|
||||
self.project,
|
||||
other,
|
||||
]
|
||||
self.assertFalse(
|
||||
self.cmd._GetPreciousObjectsState(self.project, self.opt)
|
||||
)
|
||||
|
||||
|
||||
class KeyboardInterruptTest(unittest.TestCase):
|
||||
"""Tests for KeyboardInterrupt handling in Sync operations."""
|
||||
@@ -1626,6 +1640,29 @@ class GCProjectsTest(unittest.TestCase):
|
||||
mock_set_state.assert_called_once_with(self.project, self.opt)
|
||||
self.assertFalse(self.project.bare_git.gc.called)
|
||||
|
||||
def test_GCProjects_skip_unshared_local_gitdirs(self) -> None:
|
||||
"""Unshared --use-local-gitdirs projects skip preciousObjects scan."""
|
||||
self.opt.auto_gc = False
|
||||
self.project.parent = None
|
||||
self.project.gitdir = "work/.git"
|
||||
self.project.objdir = "work/.git"
|
||||
self.project.manifest.UseLocalGitDirs = True
|
||||
self.project.manifest.GetProjectsWithName.return_value = [self.project]
|
||||
|
||||
dup = mock.MagicMock()
|
||||
dup.name = "dup"
|
||||
dup.parent = None
|
||||
dup.gitdir = "dup1/.git"
|
||||
dup.objdir = "dup1/.git"
|
||||
dup.manifest.UseLocalGitDirs = True
|
||||
dup.manifest.GetProjectsWithName.return_value = [dup, mock.MagicMock()]
|
||||
|
||||
with mock.patch.object(
|
||||
sync.Sync, "_SetPreciousObjectsState"
|
||||
) as mock_set_state:
|
||||
self.cmd._GCProjects([self.project, dup], self.opt, mock.Mock())
|
||||
mock_set_state.assert_called_once_with(dup, self.opt)
|
||||
|
||||
@mock.patch.object(progress, "Progress")
|
||||
def test_GCProjects_sequential(self, mock_progress):
|
||||
"""Test sequential GC (jobs < 2)."""
|
||||
|
||||
Reference in new issue
Block a user