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 <nasser@codeaurora.org>
Reviewed-by: David Riley <davidriley@google.com>
Reviewed-by: Mike Frysinger <vapier@google.com>
Tested-by: Mike Frysinger <vapier@google.com>
This commit is contained in:
Mike Frysinger 2020-02-11 03:23:24 -05:00
parent 163d42eb43
commit 5f2b045195

View File

@ -560,9 +560,20 @@ later is required to fix a server side protocol bug.
def _GCProjects(self, projects, opt, err_event): def _GCProjects(self, projects, opt, err_event):
gc_gitdirs = {} gc_gitdirs = {}
for project in projects: for project in projects:
# Make sure pruning never kicks in with shared projects.
if len(project.manifest.GetProjectsWithName(project.name)) > 1: if len(project.manifest.GetProjectsWithName(project.name)) > 1:
print('Shared project %s found, disabling pruning.' % project.name) print('%s: Shared project %s found, disabling pruning.' %
project.bare_git.config('--replace-all', 'gc.pruneExpire', 'never') (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 gc_gitdirs[project.gitdir] = project.bare_git
has_dash_c = git_require((1, 7, 2)) has_dash_c = git_require((1, 7, 2))