summaryrefslogtreecommitdiffstats
path: root/project.py
diff options
context:
space:
mode:
authorShawn O. Pearce <sop@google.com>2009-04-18 14:45:51 -0700
committerShawn O. Pearce <sop@google.com>2009-04-18 14:45:51 -0700
commitaccc56d82b902e7c7a22401db710958fcb1c7b58 (patch)
tree3c3d233fe188315df9d87ddc247672a92167a3f5 /project.py
parentdb45da12089bf131579d100ff7990cbc18d07325 (diff)
downloadgit-repo-accc56d82b902e7c7a22401db710958fcb1c7b58.tar.gz
Speed up 'repo start' by removing some forks
Its quite common for most projects to be matching the current manifest revision, as most developers only modify one or two projects at any one time. We can speed up `repo start foo` (that impacts the entire client) by performing most of the branch creation and switch operations in pure Python, and thus avoid 4 forks per project. Signed-off-by: Shawn O. Pearce <sop@google.com>
Diffstat (limited to 'project.py')
-rw-r--r--project.py82
1 files changed, 60 insertions, 22 deletions
diff --git a/project.py b/project.py
index 79ade3b6..8d6e4b6c 100644
--- a/project.py
+++ b/project.py
@@ -30,6 +30,21 @@ from remote import Remote
30 30
31from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M 31from git_refs import GitRefs, HEAD, R_HEADS, R_TAGS, R_PUB, R_M
32 32
33def _lwrite(path, content):
34 lock = '%s.lock' % path
35
36 fd = open(lock, 'wb')
37 try:
38 fd.write(content)
39 finally:
40 fd.close()
41
42 try:
43 os.rename(lock, path)
44 except OSError:
45 os.remove(lock)
46 raise
47
33def _error(fmt, *args): 48def _error(fmt, *args):
34 msg = fmt % args 49 msg = fmt % args
35 print >>sys.stderr, 'error: %s' % msg 50 print >>sys.stderr, 'error: %s' % msg
@@ -758,31 +773,54 @@ class Project(object):
758 def StartBranch(self, name): 773 def StartBranch(self, name):
759 """Create a new branch off the manifest's revision. 774 """Create a new branch off the manifest's revision.
760 """ 775 """
761 try: 776 head = self.work_git.GetHead()
762 self.bare_git.rev_parse(R_HEADS + name) 777 if head == (R_HEADS + name):
763 exists = True 778 return True
764 except GitError:
765 exists = False;
766 779
767 if exists: 780 all = self.bare_ref.all
768 if name == self.CurrentBranch: 781 if (R_HEADS + name) in all:
769 return True 782 cmd = ['checkout', name, '--']
770 else: 783 return GitCommand(self,
771 cmd = ['checkout', name, '--'] 784 cmd,
772 return GitCommand(self, cmd).Wait() == 0 785 capture_stdout = True).Wait() == 0
786
787 branch = self.GetBranch(name)
788 branch.remote = self.GetRemote(self.remote.name)
789 branch.merge = self.revision
773 790
791 rev = branch.LocalMerge
792 if rev in all:
793 revid = all[rev]
794 elif IsId(rev):
795 revid = rev
774 else: 796 else:
775 branch = self.GetBranch(name) 797 revid = None
776 branch.remote = self.GetRemote(self.remote.name) 798
777 branch.merge = self.revision 799 if head.startswith(R_HEADS):
778 800 try:
779 rev = branch.LocalMerge 801 head = all[head]
780 cmd = ['checkout', '-b', branch.name, rev] 802 except KeyError:
781 if GitCommand(self, cmd).Wait() == 0: 803 head = None
782 branch.Save() 804
783 return True 805 if revid and head and revid == head:
784 else: 806 ref = os.path.join(self.gitdir, R_HEADS + name)
785 return False 807 try:
808 os.makedirs(os.path.dirname(ref))
809 except OSError:
810 pass
811 _lwrite(ref, '%s\n' % revid)
812 _lwrite(os.path.join(self.worktree, '.git', HEAD),
813 'ref: %s%s\n' % (R_HEADS, name))
814 branch.Save()
815 return True
816
817 cmd = ['checkout', '-b', branch.name, rev]
818 if GitCommand(self,
819 cmd,
820 capture_stdout = True).Wait() == 0:
821 branch.Save()
822 return True
823 return False
786 824
787 def CheckoutBranch(self, name): 825 def CheckoutBranch(self, name):
788 """Checkout a local topic branch. 826 """Checkout a local topic branch.