From 5f2b04519596f285cc70717c95231ce85666e382 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 11 Feb 2020 03:23:24 -0500 Subject: [PATCH] sync: change how we preserve objects in shared repos Some automatic git operations will prune objects on us, and not just the gc step. Normally we don't care, but with shared projects, we will have multiple git checkouts with refs that the others cannot see, but with a shared object dir. Any pruning of objects based on refs in just one repo can easily break the others. git-2.7.0 introduced a preciousObjects setting which tells git to never prune objects for this exact scenario: there might be refs in some location that git is unable to see. Change-Id: I781de27c5bbe1d4c70f0187566141c9cce088bd8 Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/254392 Reviewed-by: Nasser Grainawi Reviewed-by: David Riley Reviewed-by: Mike Frysinger Tested-by: Mike Frysinger --- subcmds/sync.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/subcmds/sync.py b/subcmds/sync.py index 808df208..f41de8df 100644 --- a/subcmds/sync.py +++ b/subcmds/sync.py @@ -560,9 +560,20 @@ later is required to fix a server side protocol bug. def _GCProjects(self, projects, opt, err_event): gc_gitdirs = {} for project in projects: + # Make sure pruning never kicks in with shared projects. if len(project.manifest.GetProjectsWithName(project.name)) > 1: - print('Shared project %s found, disabling pruning.' % project.name) - project.bare_git.config('--replace-all', 'gc.pruneExpire', 'never') + print('%s: Shared project %s found, disabling pruning.' % + (project.relpath, project.name)) + if git_require((2, 7, 0)): + project.config.SetString('core.repositoryFormatVersion', '1') + project.config.SetString('extensions.preciousObjects', 'true') + else: + # This isn't perfect, but it's the best we can do with old git. + print('%s: WARNING: shared projects are unreliable when using old ' + 'versions of git; please upgrade to git-2.7.0+.' + % (project.relpath,), + file=sys.stderr) + project.config.SetString('gc.pruneExpire', 'never') gc_gitdirs[project.gitdir] = project.bare_git has_dash_c = git_require((1, 7, 2))