Merge "manifest: record the original revision when in -r mode."

This commit is contained in:
Conley Owens 2012-10-03 16:49:12 -07:00 committed by Gerrit Code Review
commit 3ff9decfd4
3 changed files with 55 additions and 17 deletions

View File

@ -124,7 +124,7 @@ class XmlManifest(object):
if r.reviewUrl is not None: if r.reviewUrl is not None:
e.setAttribute('review', r.reviewUrl) e.setAttribute('review', r.reviewUrl)
def Save(self, fd, peg_rev=False): def Save(self, fd, peg_rev=False, peg_rev_upstream=True):
"""Write the current manifest out to the given file descriptor. """Write the current manifest out to the given file descriptor.
""" """
mp = self.manifestProject mp = self.manifestProject
@ -198,11 +198,15 @@ class XmlManifest(object):
e.setAttribute('remote', p.remote.name) e.setAttribute('remote', p.remote.name)
if peg_rev: if peg_rev:
if self.IsMirror: if self.IsMirror:
e.setAttribute('revision', value = p.bare_git.rev_parse(p.revisionExpr + '^0')
p.bare_git.rev_parse(p.revisionExpr + '^0'))
else: else:
e.setAttribute('revision', value = p.work_git.rev_parse(HEAD + '^0')
p.work_git.rev_parse(HEAD + '^0')) e.setAttribute('revision', value)
if peg_rev_upstream and value != p.revisionExpr:
# Only save the origin if the origin is not a sha1, and the default
# isn't our value, and the if the default doesn't already have that
# covered.
e.setAttribute('upstream', p.revisionExpr)
elif not d.revisionExpr or p.revisionExpr != d.revisionExpr: elif not d.revisionExpr or p.revisionExpr != d.revisionExpr:
e.setAttribute('revision', p.revisionExpr) e.setAttribute('revision', p.revisionExpr)
@ -574,6 +578,8 @@ class XmlManifest(object):
else: else:
sync_c = sync_c.lower() in ("yes", "true", "1") sync_c = sync_c.lower() in ("yes", "true", "1")
upstream = node.getAttribute('upstream')
groups = '' groups = ''
if node.hasAttribute('groups'): if node.hasAttribute('groups'):
groups = node.getAttribute('groups') groups = node.getAttribute('groups')
@ -600,7 +606,8 @@ class XmlManifest(object):
revisionId = None, revisionId = None,
rebase = rebase, rebase = rebase,
groups = groups, groups = groups,
sync_c = sync_c) sync_c = sync_c,
upstream = upstream)
for n in node.childNodes: for n in node.childNodes:
if n.nodeName == 'copyfile': if n.nodeName == 'copyfile':

View File

@ -484,7 +484,8 @@ class Project(object):
revisionId, revisionId,
rebase = True, rebase = True,
groups = None, groups = None,
sync_c = False): sync_c = False,
upstream = None):
self.manifest = manifest self.manifest = manifest
self.name = name self.name = name
self.remote = remote self.remote = remote
@ -506,6 +507,7 @@ class Project(object):
self.rebase = rebase self.rebase = rebase
self.groups = groups self.groups = groups
self.sync_c = sync_c self.sync_c = sync_c
self.upstream = upstream
self.snapshots = {} self.snapshots = {}
self.copyfiles = [] self.copyfiles = []
@ -1373,6 +1375,16 @@ class Project(object):
is_sha1 = False is_sha1 = False
tag_name = None tag_name = None
def CheckForSha1():
try:
# if revision (sha or tag) is not present then following function
# throws an error.
self.bare_git.rev_parse('--verify', '%s^0' % self.revisionExpr)
return True
except GitError:
# There is no such persistent revision. We have to fetch it.
return False
if current_branch_only: if current_branch_only:
if ID_RE.match(self.revisionExpr) is not None: if ID_RE.match(self.revisionExpr) is not None:
is_sha1 = True is_sha1 = True
@ -1381,14 +1393,10 @@ class Project(object):
tag_name = self.revisionExpr[len(R_TAGS):] tag_name = self.revisionExpr[len(R_TAGS):]
if is_sha1 or tag_name is not None: if is_sha1 or tag_name is not None:
try: if CheckForSha1():
# if revision (sha or tag) is not present then following function
# throws an error.
self.bare_git.rev_parse('--verify', '%s^0' % self.revisionExpr)
return True return True
except GitError: if is_sha1 and (not self.upstream or ID_RE.match(self.upstream)):
# There is no such persistent revision. We have to fetch it. current_branch_only = False
pass
if not name: if not name:
name = self.remote.name name = self.remote.name
@ -1453,7 +1461,7 @@ class Project(object):
cmd.append('--update-head-ok') cmd.append('--update-head-ok')
cmd.append(name) cmd.append(name)
if not current_branch_only or is_sha1: if not current_branch_only:
# Fetch whole repo # Fetch whole repo
cmd.append('--tags') cmd.append('--tags')
cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*')) cmd.append((u'+refs/heads/*:') + remote.ToLocal('refs/heads/*'))
@ -1462,15 +1470,23 @@ class Project(object):
cmd.append(tag_name) cmd.append(tag_name)
else: else:
branch = self.revisionExpr branch = self.revisionExpr
if is_sha1:
branch = self.upstream
if branch.startswith(R_HEADS): if branch.startswith(R_HEADS):
branch = branch[len(R_HEADS):] branch = branch[len(R_HEADS):]
cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch)) cmd.append((u'+refs/heads/%s:' % branch) + remote.ToLocal('refs/heads/%s' % branch))
ok = False ok = False
for i in range(2): for i in range(2):
if GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy).Wait() == 0: ret = GitCommand(self, cmd, bare=True, ssh_proxy=ssh_proxy).Wait()
if ret == 0:
ok = True ok = True
break break
elif current_branch_only and is_sha1 and ret == 128:
# Exit code 128 means "couldn't find the ref you asked for"; if we're in sha1
# mode, we just tried sync'ing from the upstream field; it doesn't exist, thus
# abort the optimization attempt and do a full sync.
break
time.sleep(random.randint(30, 45)) time.sleep(random.randint(30, 45))
if initial: if initial:
@ -1480,6 +1496,15 @@ class Project(object):
else: else:
os.remove(packed_refs) os.remove(packed_refs)
self.bare_git.pack_refs('--all', '--prune') self.bare_git.pack_refs('--all', '--prune')
if is_sha1 and current_branch_only and self.upstream:
# We just synced the upstream given branch; verify we
# got what we wanted, else trigger a second run of all
# refs.
if not CheckForSha1():
return self._RemoteFetch(name=name, current_branch_only=False,
initial=False, quiet=quiet, alt_dir=alt_dir)
return ok return ok
def _ApplyCloneBundle(self, initial=False, quiet=False): def _ApplyCloneBundle(self, initial=False, quiet=False):

View File

@ -48,6 +48,11 @@ in a Git repository for use during future 'repo init' invocations.
p.add_option('-r', '--revision-as-HEAD', p.add_option('-r', '--revision-as-HEAD',
dest='peg_rev', action='store_true', dest='peg_rev', action='store_true',
help='Save revisions as current HEAD') help='Save revisions as current HEAD')
p.add_option('--suppress-upstream-revision', dest='peg_rev_upstream',
default=True, action='store_false',
help='If in -r mode, do not write the upstream field. '
'Only of use if the branch names for a sha1 manifest are '
'sensitive.')
p.add_option('-o', '--output-file', p.add_option('-o', '--output-file',
dest='output_file', dest='output_file',
default='-', default='-',
@ -60,7 +65,8 @@ in a Git repository for use during future 'repo init' invocations.
else: else:
fd = open(opt.output_file, 'w') fd = open(opt.output_file, 'w')
self.manifest.Save(fd, self.manifest.Save(fd,
peg_rev = opt.peg_rev) peg_rev = opt.peg_rev,
peg_rev_upstream = opt.peg_rev_upstream)
fd.close() fd.close()
if opt.output_file != '-': if opt.output_file != '-':
print >>sys.stderr, 'Saved manifest to %s' % opt.output_file print >>sys.stderr, 'Saved manifest to %s' % opt.output_file