summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-04-17 20:58:02 -0700
committerShawn O. Pearce <sop@google.com>2009-04-17 21:03:45 -0700
commitfbcde472cadfc8319016faca90cb5b57f7a00ee4 (patch)
treeee0b2eb641c2874f5d150d0e5b1556778e308b42
parentd237b698652120f4d859b6f9e12e3aa15aa7b2d5 (diff)
downloadgit-repo-fbcde472cadfc8319016faca90cb5b57f7a00ee4.tar.gz
Improve repo sync performance by avoid git forks
By resolving the current HEAD and the manifest revision using pure Python, we can in the common case of "no changes" avoid a lot of git operations and directly jump out of the local sync method. This reduces the no-op `repo sync -l` time for Android's 114 projects from more than 6s to under 0.8s. Signed-off-by: Shawn O. Pearce <sop@google.com>
-rw-r--r--git_refs.py11
-rw-r--r--project.py64
2 files changed, 60 insertions, 15 deletions
diff --git a/git_refs.py b/git_refs.py
index 9851e78b..eefa2abe 100644
--- a/git_refs.py
+++ b/git_refs.py
@@ -41,6 +41,17 @@ class GitRefs(object):
41 except KeyError: 41 except KeyError:
42 return '' 42 return ''
43 43
44 def deleted(self, name):
45 if self._phyref is not None:
46 if name in self._phyref:
47 del self._phyref[name]
48
49 if name in self._symref:
50 del self._symref[name]
51
52 if name in self._mtime:
53 del self._mtime[name]
54
44 def _NeedUpdate(self): 55 def _NeedUpdate(self):
45 for name, mtime in self._mtime.iteritems(): 56 for name, mtime in self._mtime.iteritems():
46 try: 57 try:
diff --git a/project.py b/project.py
index 086f0d77..9f9cf7bf 100644
--- a/project.py
+++ b/project.py
@@ -416,22 +416,31 @@ class Project(object):
416 416
417## Publish / Upload ## 417## Publish / Upload ##
418 418
419 def WasPublished(self, branch): 419 def WasPublished(self, branch, all=None):
420 """Was the branch published (uploaded) for code review? 420 """Was the branch published (uploaded) for code review?
421 If so, returns the SHA-1 hash of the last published 421 If so, returns the SHA-1 hash of the last published
422 state for the branch. 422 state for the branch.
423 """ 423 """
424 try: 424 key = R_PUB + branch
425 return self.bare_git.rev_parse(R_PUB + branch) 425 if all is None:
426 except GitError: 426 try:
427 return None 427 return self.bare_git.rev_parse(key)
428 except GitError:
429 return None
430 else:
431 try:
432 return all[key]
433 except KeyError:
434 return None
428 435
429 def CleanPublishedCache(self): 436 def CleanPublishedCache(self, all=None):
430 """Prunes any stale published refs. 437 """Prunes any stale published refs.
431 """ 438 """
439 if all is None:
440 all = self._allrefs
432 heads = set() 441 heads = set()
433 canrm = {} 442 canrm = {}
434 for name, id in self._allrefs.iteritems(): 443 for name, id in all.iteritems():
435 if name.startswith(R_HEADS): 444 if name.startswith(R_HEADS):
436 heads.add(name) 445 heads.add(name)
437 elif name.startswith(R_PUB): 446 elif name.startswith(R_PUB):
@@ -567,17 +576,31 @@ class Project(object):
567 Network access is not required. 576 Network access is not required.
568 """ 577 """
569 self._InitWorkTree() 578 self._InitWorkTree()
570 self.CleanPublishedCache() 579 all = self.bare_ref.all
580 self.CleanPublishedCache(all)
571 581
572 rem = self.GetRemote(self.remote.name) 582 rem = self.GetRemote(self.remote.name)
573 rev = rem.ToLocal(self.revision) 583 rev = rem.ToLocal(self.revision)
574 try: 584 if rev in all:
575 self.bare_git.rev_parse('--verify', '%s^0' % rev) 585 revid = all[rev]
576 except GitError: 586 elif IsId(rev):
577 raise ManifestInvalidRevisionError( 587 revid = rev
578 'revision %s in %s not found' % (self.revision, self.name)) 588 else:
589 try:
590 revid = self.bare_git.rev_parse('--verify', '%s^0' % rev)
591 except GitError:
592 raise ManifestInvalidRevisionError(
593 'revision %s in %s not found' % (self.revision, self.name))
579 594
580 branch = self.CurrentBranch 595 head = self.work_git.GetHead()
596 if head.startswith(R_HEADS):
597 branch = head[len(R_HEADS):]
598 try:
599 head = all[head]
600 except KeyError:
601 head = None
602 else:
603 branch = None
581 604
582 if branch is None or syncbuf.detach_head: 605 if branch is None or syncbuf.detach_head:
583 # Currently on a detached HEAD. The user is assumed to 606 # Currently on a detached HEAD. The user is assumed to
@@ -588,6 +611,11 @@ class Project(object):
588 syncbuf.fail(self, _PriorSyncFailedError()) 611 syncbuf.fail(self, _PriorSyncFailedError())
589 return 612 return
590 613
614 if head == revid:
615 # No changes; don't do anything further.
616 #
617 return
618
591 lost = self._revlist(not_rev(rev), HEAD) 619 lost = self._revlist(not_rev(rev), HEAD)
592 if lost: 620 if lost:
593 syncbuf.info(self, "discarding %d commits", len(lost)) 621 syncbuf.info(self, "discarding %d commits", len(lost))
@@ -599,6 +627,11 @@ class Project(object):
599 self._CopyFiles() 627 self._CopyFiles()
600 return 628 return
601 629
630 if head == revid:
631 # No changes; don't do anything further.
632 #
633 return
634
602 branch = self.GetBranch(branch) 635 branch = self.GetBranch(branch)
603 merge = branch.LocalMerge 636 merge = branch.LocalMerge
604 637
@@ -618,7 +651,7 @@ class Project(object):
618 return 651 return
619 652
620 upstream_gain = self._revlist(not_rev(HEAD), rev) 653 upstream_gain = self._revlist(not_rev(HEAD), rev)
621 pub = self.WasPublished(branch.name) 654 pub = self.WasPublished(branch.name, all)
622 if pub: 655 if pub:
623 not_merged = self._revlist(not_rev(rev), pub) 656 not_merged = self._revlist(not_rev(rev), pub)
624 if not_merged: 657 if not_merged:
@@ -1142,6 +1175,7 @@ class Project(object):
1142 if not old: 1175 if not old:
1143 old = self.rev_parse(name) 1176 old = self.rev_parse(name)
1144 self.update_ref('-d', name, old) 1177 self.update_ref('-d', name, old)
1178 self._project.bare_ref.deleted(name)
1145 1179
1146 def rev_list(self, *args): 1180 def rev_list(self, *args):
1147 cmdv = ['rev-list'] 1181 cmdv = ['rev-list']