mirror of
https://gerrit.googlesource.com/git-repo
synced 2024-12-21 07:16:21 +00:00
Improve checkout performance for the common unmodified case
Most projects will have their branch heads matching in all branches, so switching between them should be just a matter of updating the work tree's HEAD symref. This can be done in pure Python, saving quite a bit of time over forking 'git checkout'. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
parent
0f0dfa3930
commit
89e717d948
43
project.py
43
project.py
@ -779,9 +779,8 @@ class Project(object):
|
|||||||
|
|
||||||
all = self.bare_ref.all
|
all = self.bare_ref.all
|
||||||
if (R_HEADS + name) in all:
|
if (R_HEADS + name) in all:
|
||||||
cmd = ['checkout', name, '--']
|
|
||||||
return GitCommand(self,
|
return GitCommand(self,
|
||||||
cmd,
|
['checkout', name, '--'],
|
||||||
capture_stdout = True,
|
capture_stdout = True,
|
||||||
capture_stderr = True).Wait() == 0
|
capture_stderr = True).Wait() == 0
|
||||||
|
|
||||||
@ -815,9 +814,8 @@ class Project(object):
|
|||||||
branch.Save()
|
branch.Save()
|
||||||
return True
|
return True
|
||||||
|
|
||||||
cmd = ['checkout', '-b', branch.name, rev]
|
|
||||||
if GitCommand(self,
|
if GitCommand(self,
|
||||||
cmd,
|
['checkout', '-b', branch.name, rev],
|
||||||
capture_stdout = True,
|
capture_stdout = True,
|
||||||
capture_stderr = True).Wait() == 0:
|
capture_stderr = True).Wait() == 0:
|
||||||
branch.Save()
|
branch.Save()
|
||||||
@ -827,16 +825,39 @@ class Project(object):
|
|||||||
def CheckoutBranch(self, name):
|
def CheckoutBranch(self, name):
|
||||||
"""Checkout a local topic branch.
|
"""Checkout a local topic branch.
|
||||||
"""
|
"""
|
||||||
|
rev = R_HEADS + name
|
||||||
|
head = self.work_git.GetHead()
|
||||||
|
if head == rev:
|
||||||
|
# Already on the branch
|
||||||
|
#
|
||||||
|
return True
|
||||||
|
|
||||||
# Be sure the branch exists
|
all = self.bare_ref.all
|
||||||
try:
|
try:
|
||||||
tip_rev = self.bare_git.rev_parse(R_HEADS + name)
|
revid = all[rev]
|
||||||
except GitError:
|
except KeyError:
|
||||||
return False;
|
# Branch does not exist in this project
|
||||||
|
#
|
||||||
|
return False
|
||||||
|
|
||||||
# Do the checkout
|
if head.startswith(R_HEADS):
|
||||||
cmd = ['checkout', name, '--']
|
try:
|
||||||
return GitCommand(self, cmd).Wait() == 0
|
head = all[head]
|
||||||
|
except KeyError:
|
||||||
|
head = None
|
||||||
|
|
||||||
|
if head == revid:
|
||||||
|
# Same revision; just update HEAD to point to the new
|
||||||
|
# target branch, but otherwise take no other action.
|
||||||
|
#
|
||||||
|
_lwrite(os.path.join(self.worktree, '.git', HEAD),
|
||||||
|
'ref: %s%s\n' % (R_HEADS, name))
|
||||||
|
return True
|
||||||
|
|
||||||
|
return GitCommand(self,
|
||||||
|
['checkout', name, '--'],
|
||||||
|
capture_stdout = True,
|
||||||
|
capture_stderr = True).Wait() == 0
|
||||||
|
|
||||||
def AbandonBranch(self, name):
|
def AbandonBranch(self, name):
|
||||||
"""Destroy a local topic branch.
|
"""Destroy a local topic branch.
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
|
|
||||||
import sys
|
import sys
|
||||||
from command import Command
|
from command import Command
|
||||||
|
from progress import Progress
|
||||||
|
|
||||||
class Checkout(Command):
|
class Checkout(Command):
|
||||||
common = True
|
common = True
|
||||||
@ -35,13 +36,23 @@ The command is equivalent to:
|
|||||||
if not args:
|
if not args:
|
||||||
self.Usage()
|
self.Usage()
|
||||||
|
|
||||||
retValue = 0;
|
nb = args[0]
|
||||||
|
err = []
|
||||||
|
all = self.GetProjects(args[1:])
|
||||||
|
|
||||||
branch = args[0]
|
pm = Progress('Checkout %s' % nb, len(all))
|
||||||
for project in self.GetProjects(args[1:]):
|
for project in all:
|
||||||
if not project.CheckoutBranch(branch):
|
pm.update()
|
||||||
retValue = 1;
|
if not project.CheckoutBranch(nb):
|
||||||
print >>sys.stderr, "error: checking out branch '%s' in %s failed" % (branch, project.name)
|
err.append(project)
|
||||||
|
pm.end()
|
||||||
|
|
||||||
if (retValue != 0):
|
if err:
|
||||||
sys.exit(retValue);
|
if len(err) == len(all):
|
||||||
|
print >>sys.stderr, 'error: no project has branch %s' % nb
|
||||||
|
else:
|
||||||
|
for p in err:
|
||||||
|
print >>sys.stderr,\
|
||||||
|
"error: %s/: cannot checkout %s" \
|
||||||
|
% (p.relpath, nb)
|
||||||
|
sys.exit(1)
|
||||||
|
@ -49,7 +49,8 @@ revision specified in the manifest.
|
|||||||
pm.end()
|
pm.end()
|
||||||
|
|
||||||
if err:
|
if err:
|
||||||
err.sort()
|
|
||||||
for p in err:
|
for p in err:
|
||||||
print >>sys.stderr, "error: cannot start in %s" % p.relpath
|
print >>sys.stderr,\
|
||||||
|
"error: %s/: cannot start %s" \
|
||||||
|
% (p.relpath, nb)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
Loading…
Reference in New Issue
Block a user