summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Frysinger <vapier@google.com>2021-05-01 12:02:01 -0400
committerMike Frysinger <vapier@google.com>2021-05-02 00:06:32 +0000
commitd1f3e149df4482ee24feee038c88df32fbc77380 (patch)
treebd3b30c8788d8f130a32ebe45fe877e6aec64d99
parent29626b4f463d12186d9ce96e07063214347ead18 (diff)
downloadgit-repo-d1f3e149df4482ee24feee038c88df32fbc77380.tar.gz
upload: search local projects in parallel
Search for project branches to upload in parallel. This can cut the lookup time in half for large projects. We still run the actual hooks in serial once we have the list of projects to process, but we would need to rethink things quite a bit before we could handle running them in parallel too. Change-Id: I8da0cbc5010566aa860e1a158f3dc07f0709dcff Reviewed-on: https://gerrit-review.googlesource.com/c/git-repo/+/304842 Reviewed-by: Raman Tenneti <rtenneti@google.com> Tested-by: Mike Frysinger <vapier@google.com>
-rw-r--r--subcmds/upload.py68
1 files changed, 37 insertions, 31 deletions
diff --git a/subcmds/upload.py b/subcmds/upload.py
index a23755c7..0dd0b7da 100644
--- a/subcmds/upload.py
+++ b/subcmds/upload.py
@@ -13,10 +13,11 @@
13# limitations under the License. 13# limitations under the License.
14 14
15import copy 15import copy
16import functools
16import re 17import re
17import sys 18import sys
18 19
19from command import InteractiveCommand 20from command import DEFAULT_LOCAL_JOBS, InteractiveCommand
20from editor import Editor 21from editor import Editor
21from error import UploadError 22from error import UploadError
22from git_command import GitCommand 23from git_command import GitCommand
@@ -145,6 +146,7 @@ https://gerrit-review.googlesource.com/Documentation/user-upload.html#notify
145Gerrit Code Review: https://www.gerritcodereview.com/ 146Gerrit Code Review: https://www.gerritcodereview.com/
146 147
147""" 148"""
149 PARALLEL_JOBS = DEFAULT_LOCAL_JOBS
148 150
149 def _Options(self, p): 151 def _Options(self, p):
150 p.add_option('-t', 152 p.add_option('-t',
@@ -165,9 +167,9 @@ Gerrit Code Review: https://www.gerritcodereview.com/
165 p.add_option('--cc', 167 p.add_option('--cc',
166 type='string', action='append', dest='cc', 168 type='string', action='append', dest='cc',
167 help='Also send email to these email addresses.') 169 help='Also send email to these email addresses.')
168 p.add_option('--br', 170 p.add_option('--br', '--branch',
169 type='string', action='store', dest='branch', 171 type='string', action='store', dest='branch',
170 help='Branch to upload.') 172 help='(Local) branch to upload.')
171 p.add_option('--cbr', '--current-branch', 173 p.add_option('--cbr', '--current-branch',
172 dest='current_branch', action='store_true', 174 dest='current_branch', action='store_true',
173 help='Upload current git branch.') 175 help='Upload current git branch.')
@@ -502,40 +504,46 @@ Gerrit Code Review: https://www.gerritcodereview.com/
502 merge_branch = p.stdout.strip() 504 merge_branch = p.stdout.strip()
503 return merge_branch 505 return merge_branch
504 506
507 @staticmethod
508 def _GatherOne(opt, project):
509 """Figure out the upload status for |project|."""
510 if opt.current_branch:
511 cbr = project.CurrentBranch
512 up_branch = project.GetUploadableBranch(cbr)
513 avail = [up_branch] if up_branch else None
514 else:
515 avail = project.GetUploadableBranches(opt.branch)
516 return (project, avail)
517
505 def Execute(self, opt, args): 518 def Execute(self, opt, args):
506 project_list = self.GetProjects(args) 519 projects = self.GetProjects(args)
507 pending = [] 520
508 reviewers = [] 521 def _ProcessResults(_pool, _out, results):
509 cc = [] 522 pending = []
510 branch = None 523 for result in results:
511 524 project, avail = result
512 if opt.branch: 525 if avail is None:
513 branch = opt.branch
514
515 for project in project_list:
516 if opt.current_branch:
517 cbr = project.CurrentBranch
518 up_branch = project.GetUploadableBranch(cbr)
519 if up_branch:
520 avail = [up_branch]
521 else:
522 avail = None
523 print('repo: error: %s: Unable to upload branch "%s". ' 526 print('repo: error: %s: Unable to upload branch "%s". '
524 'You might be able to fix the branch by running:\n' 527 'You might be able to fix the branch by running:\n'
525 ' git branch --set-upstream-to m/%s' % 528 ' git branch --set-upstream-to m/%s' %
526 (project.relpath, str(cbr), self.manifest.branch), 529 (project.relpath, project.CurrentBranch, self.manifest.branch),
527 file=sys.stderr) 530 file=sys.stderr)
528 else: 531 elif avail:
529 avail = project.GetUploadableBranches(branch) 532 pending.append(result)
530 if avail: 533 return pending
531 pending.append((project, avail)) 534
535 pending = self.ExecuteInParallel(
536 opt.jobs,
537 functools.partial(self._GatherOne, opt),
538 projects,
539 callback=_ProcessResults)
532 540
533 if not pending: 541 if not pending:
534 if branch is None: 542 if opt.branch is None:
535 print('repo: error: no branches ready for upload', file=sys.stderr) 543 print('repo: error: no branches ready for upload', file=sys.stderr)
536 else: 544 else:
537 print('repo: error: no branches named "%s" ready for upload' % 545 print('repo: error: no branches named "%s" ready for upload' %
538 (branch,), file=sys.stderr) 546 (opt.branch,), file=sys.stderr)
539 return 1 547 return 1
540 548
541 pending_proj_names = [project.name for (project, available) in pending] 549 pending_proj_names = [project.name for (project, available) in pending]
@@ -548,10 +556,8 @@ Gerrit Code Review: https://www.gerritcodereview.com/
548 worktree_list=pending_worktrees): 556 worktree_list=pending_worktrees):
549 return 1 557 return 1
550 558
551 if opt.reviewers: 559 reviewers = _SplitEmails(opt.reviewers) if opt.reviewers else []
552 reviewers = _SplitEmails(opt.reviewers) 560 cc = _SplitEmails(opt.cc) if opt.cc else []
553 if opt.cc:
554 cc = _SplitEmails(opt.cc)
555 people = (reviewers, cc) 561 people = (reviewers, cc)
556 562
557 if len(pending) == 1 and len(pending[0][1]) == 1: 563 if len(pending) == 1 and len(pending[0][1]) == 1: