subcmds/sync: Use pack-refs instead of gc for redundant gitdirs.
Previously `git gc` was being run on every gitdir even when they shared
the same objects. Instead only call it once and use pack-refs for the
gitdirs that were not gc'ed.
Bug: https://crbug.com/gerrit/15113
Test: repo sync -j # and check that git pack-refs is called
Change-Id: Icff37ab3ec78cfb44391d8cc7f2d875991532320
Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/320275
Tested-by: Allen Webb <allenwebb@google.com>
Reviewed-by: Mike Frysinger <vapier@google.com>
diff --git a/subcmds/sync.py b/subcmds/sync.py
index 83d6ca1..7318516 100644
--- a/subcmds/sync.py
+++ b/subcmds/sync.py
@@ -605,7 +605,7 @@
pm = Progress('Garbage collecting', len(projects), delay=False, quiet=opt.quiet)
pm.update(inc=0, msg='prescan')
- gc_gitdirs = {}
+ tidy_dirs = {}
for project in projects:
# Make sure pruning never kicks in with shared projects.
if (not project.use_git_worktrees and
@@ -623,17 +623,28 @@
file=sys.stderr)
project.config.SetString('gc.pruneExpire', 'never')
project.config.SetString('gc.autoDetach', 'false')
- gc_gitdirs[project.gitdir] = project.bare_git
-
- pm.update(inc=len(projects) - len(gc_gitdirs), msg='warming up')
+ # Only call git gc once per objdir, but call pack-refs for the remainder.
+ if project.objdir not in tidy_dirs:
+ tidy_dirs[project.objdir] = (
+ True, # Run a full gc.
+ project.bare_git,
+ )
+ elif project.gitdir not in tidy_dirs:
+ tidy_dirs[project.gitdir] = (
+ False, # Do not run a full gc; just run pack-refs.
+ project.bare_git,
+ )
cpu_count = os.cpu_count()
jobs = min(self.jobs, cpu_count)
if jobs < 2:
- for bare_git in gc_gitdirs.values():
+ for (run_gc, bare_git) in tidy_dirs.values():
pm.update(msg=bare_git._project.name)
- bare_git.gc('--auto')
+ if run_gc:
+ bare_git.gc('--auto')
+ else:
+ bare_git.pack_refs()
pm.end()
return
@@ -642,11 +653,14 @@
threads = set()
sem = _threading.Semaphore(jobs)
- def GC(bare_git):
+ def tidy_up(run_gc, bare_git):
pm.start(bare_git._project.name)
try:
try:
- bare_git.gc('--auto', config=config)
+ if run_gc:
+ bare_git.gc('--auto', config=config)
+ else:
+ bare_git.pack_refs(config=config)
except GitError:
err_event.set()
except Exception:
@@ -656,11 +670,11 @@
pm.finish(bare_git._project.name)
sem.release()
- for bare_git in gc_gitdirs.values():
+ for (run_gc, bare_git) in tidy_dirs.values():
if err_event.is_set() and opt.fail_fast:
break
sem.acquire()
- t = _threading.Thread(target=GC, args=(bare_git,))
+ t = _threading.Thread(target=tidy_up, args=(run_gc, bare_git,))
t.daemon = True
threads.add(t)
t.start()