|
@@ -303,12 +303,12 @@ class GitWrapper(SCMWrapper):
|
|
except OSError:
|
|
except OSError:
|
|
pass
|
|
pass
|
|
|
|
|
|
- def _FetchAndReset(self, revision, file_list, options):
|
|
|
|
|
|
+ def _FetchAndReset(self, ref, remote_ref, revision, file_list, options):
|
|
"""Equivalent to git fetch; git reset."""
|
|
"""Equivalent to git fetch; git reset."""
|
|
- self._UpdateBranchHeads(options, fetch=False)
|
|
|
|
|
|
+ self._UpdateBranchHeads(options, ref, remote_ref, fetch=False)
|
|
|
|
|
|
self._Fetch(options, prune=True, quiet=options.verbose)
|
|
self._Fetch(options, prune=True, quiet=options.verbose)
|
|
- self._Scrub(revision, options)
|
|
|
|
|
|
+ self._Scrub(revision or remote_ref, options)
|
|
if file_list is not None:
|
|
if file_list is not None:
|
|
files = self._Capture(
|
|
files = self._Capture(
|
|
['-c', 'core.quotePath=false', 'ls-files']).splitlines()
|
|
['-c', 'core.quotePath=false', 'ls-files']).splitlines()
|
|
@@ -384,11 +384,12 @@ class GitWrapper(SCMWrapper):
|
|
|
|
|
|
self._CheckMinVersion("1.6.6")
|
|
self._CheckMinVersion("1.6.6")
|
|
|
|
|
|
- # If a dependency is not pinned, track the default remote branch.
|
|
|
|
- default_rev = 'refs/remotes/%s/master' % self.remote
|
|
|
|
|
|
+ # If a dependency is not pinned, track refs/heads/master by default.
|
|
|
|
+ default_rev = 'refs/heads/master'
|
|
url, deps_revision = gclient_utils.SplitUrlRevision(self.url)
|
|
url, deps_revision = gclient_utils.SplitUrlRevision(self.url)
|
|
revision = deps_revision
|
|
revision = deps_revision
|
|
managed = True
|
|
managed = True
|
|
|
|
+
|
|
if options.revision:
|
|
if options.revision:
|
|
# Override the revision number.
|
|
# Override the revision number.
|
|
revision = str(options.revision)
|
|
revision = str(options.revision)
|
|
@@ -410,20 +411,37 @@ class GitWrapper(SCMWrapper):
|
|
verbose = ['--verbose']
|
|
verbose = ['--verbose']
|
|
printed_path = True
|
|
printed_path = True
|
|
|
|
|
|
- remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote)
|
|
|
|
- if remote_ref:
|
|
|
|
- # Rewrite remote refs to their local equivalents.
|
|
|
|
- revision = ''.join(remote_ref)
|
|
|
|
- rev_type = "branch"
|
|
|
|
- elif revision.startswith('refs/'):
|
|
|
|
- # Local branch? We probably don't want to support, since DEPS should
|
|
|
|
- # always specify branches as they are in the upstream repo.
|
|
|
|
- rev_type = "branch"
|
|
|
|
- else:
|
|
|
|
- # hash is also a tag, only make a distinction at checkout
|
|
|
|
- rev_type = "hash"
|
|
|
|
|
|
+ ref = remote_ref = None
|
|
|
|
+ # Support the 'branch:revision' syntax.
|
|
|
|
+ if ':' in revision:
|
|
|
|
+ ref, revision = revision.split(':')
|
|
|
|
+ if not gclient_utils.IsFullGitSha(revision):
|
|
|
|
+ raise gclient_utils.Error(
|
|
|
|
+ 'Invalid format: %s:%s. revision must be a git hash.' % (
|
|
|
|
+ remote_ref, revision))
|
|
|
|
+ elif not gclient_utils.IsFullGitSha(revision):
|
|
|
|
+ ref = revision
|
|
|
|
+ revision = None
|
|
|
|
+
|
|
|
|
+ if ref:
|
|
|
|
+ if ref.startswith('origin/'):
|
|
|
|
+ ref = ref[len('origin/'):]
|
|
|
|
+ if not ref.startswith('refs/'):
|
|
|
|
+ ref = 'refs/heads/' + ref
|
|
|
|
+ remote_ref = scm.GIT.RefToRemoteRef(ref, self.remote)
|
|
|
|
+ if remote_ref:
|
|
|
|
+ # If there is a corresponding remote ref for |ref|, RefToRemoteRef
|
|
|
|
+ # returns a tuple, so we need to join it to get the actual remote ref.
|
|
|
|
+ # E.g. ('refs/remotes/origin/', 'branch-name')
|
|
|
|
+ # -> 'refs/remotes/origin/branch-name
|
|
|
|
+ remote_ref = ''.join(remote_ref)
|
|
|
|
+ else:
|
|
|
|
+ # Otherwise, it returns None, so we use |ref|.
|
|
|
|
+ remote_ref = ref
|
|
|
|
|
|
- mirror = self._GetMirror(url, options)
|
|
|
|
|
|
+ # If we're using a mirror, make sure it contains the ref we are asked to
|
|
|
|
+ # sync.
|
|
|
|
+ mirror = self._GetMirror(url, options, ref)
|
|
if mirror:
|
|
if mirror:
|
|
url = mirror.mirror_path
|
|
url = mirror.mirror_path
|
|
|
|
|
|
@@ -445,12 +463,12 @@ class GitWrapper(SCMWrapper):
|
|
(os.path.isdir(self.checkout_path) and
|
|
(os.path.isdir(self.checkout_path) and
|
|
not os.path.exists(os.path.join(self.checkout_path, '.git')))):
|
|
not os.path.exists(os.path.join(self.checkout_path, '.git')))):
|
|
if mirror:
|
|
if mirror:
|
|
- self._UpdateMirrorIfNotContains(mirror, options, rev_type, revision)
|
|
|
|
|
|
+ self._UpdateMirrorIfNotContains(mirror, options, revision)
|
|
try:
|
|
try:
|
|
- self._Clone(revision, url, options)
|
|
|
|
|
|
+ self._Clone(ref, remote_ref, revision, url, options)
|
|
except subprocess2.CalledProcessError:
|
|
except subprocess2.CalledProcessError:
|
|
self._DeleteOrMove(options.force)
|
|
self._DeleteOrMove(options.force)
|
|
- self._Clone(revision, url, options)
|
|
|
|
|
|
+ self._Clone(ref, remote_ref, revision, url, options)
|
|
if file_list is not None:
|
|
if file_list is not None:
|
|
files = self._Capture(
|
|
files = self._Capture(
|
|
['-c', 'core.quotePath=false', 'ls-files']).splitlines()
|
|
['-c', 'core.quotePath=false', 'ls-files']).splitlines()
|
|
@@ -462,14 +480,14 @@ class GitWrapper(SCMWrapper):
|
|
return self._Capture(['rev-parse', '--verify', 'HEAD'])
|
|
return self._Capture(['rev-parse', '--verify', 'HEAD'])
|
|
|
|
|
|
if not managed:
|
|
if not managed:
|
|
- self._UpdateBranchHeads(options, fetch=False)
|
|
|
|
|
|
+ self._UpdateBranchHeads(options, ref, remote_ref, fetch=False)
|
|
self.Print('________ unmanaged solution; skipping %s' % self.relpath)
|
|
self.Print('________ unmanaged solution; skipping %s' % self.relpath)
|
|
return self._Capture(['rev-parse', '--verify', 'HEAD'])
|
|
return self._Capture(['rev-parse', '--verify', 'HEAD'])
|
|
|
|
|
|
self._maybe_break_locks(options)
|
|
self._maybe_break_locks(options)
|
|
|
|
|
|
if mirror:
|
|
if mirror:
|
|
- self._UpdateMirrorIfNotContains(mirror, options, rev_type, revision)
|
|
|
|
|
|
+ self._UpdateMirrorIfNotContains(mirror, options, revision)
|
|
|
|
|
|
# See if the url has changed (the unittests use git://foo for the url, let
|
|
# See if the url has changed (the unittests use git://foo for the url, let
|
|
# that through).
|
|
# that through).
|
|
@@ -496,12 +514,14 @@ class GitWrapper(SCMWrapper):
|
|
self.checkout_path, '.git', 'objects', 'info', 'alternates'),
|
|
self.checkout_path, '.git', 'objects', 'info', 'alternates'),
|
|
'w') as fh:
|
|
'w') as fh:
|
|
fh.write(os.path.join(url, 'objects'))
|
|
fh.write(os.path.join(url, 'objects'))
|
|
- self._EnsureValidHeadObjectOrCheckout(revision, options, url)
|
|
|
|
- self._FetchAndReset(revision, file_list, options)
|
|
|
|
|
|
+ self._EnsureValidHeadObjectOrCheckout(ref, remote_ref, revision, options,
|
|
|
|
+ url)
|
|
|
|
+ self._FetchAndReset(ref, remote_ref, revision, file_list, options)
|
|
|
|
|
|
return_early = True
|
|
return_early = True
|
|
else:
|
|
else:
|
|
- self._EnsureValidHeadObjectOrCheckout(revision, options, url)
|
|
|
|
|
|
+ self._EnsureValidHeadObjectOrCheckout(ref, remote_ref, revision, options,
|
|
|
|
+ url)
|
|
|
|
|
|
if return_early:
|
|
if return_early:
|
|
return self._Capture(['rev-parse', '--verify', 'HEAD'])
|
|
return self._Capture(['rev-parse', '--verify', 'HEAD'])
|
|
@@ -547,16 +567,17 @@ class GitWrapper(SCMWrapper):
|
|
else:
|
|
else:
|
|
raise gclient_utils.Error('Invalid Upstream: %s' % upstream_branch)
|
|
raise gclient_utils.Error('Invalid Upstream: %s' % upstream_branch)
|
|
|
|
|
|
- if not scm.GIT.IsValidRevision(self.checkout_path, revision, sha_only=True):
|
|
|
|
|
|
+ if revision and not scm.GIT.IsValidRevision(
|
|
|
|
+ self.checkout_path, revision, sha_only=True):
|
|
# Update the remotes first so we have all the refs.
|
|
# Update the remotes first so we have all the refs.
|
|
remote_output = scm.GIT.Capture(['remote'] + verbose + ['update'],
|
|
remote_output = scm.GIT.Capture(['remote'] + verbose + ['update'],
|
|
cwd=self.checkout_path)
|
|
cwd=self.checkout_path)
|
|
if verbose:
|
|
if verbose:
|
|
self.Print(remote_output)
|
|
self.Print(remote_output)
|
|
|
|
|
|
- self._UpdateBranchHeads(options, fetch=True)
|
|
|
|
|
|
+ self._UpdateBranchHeads(options, ref, remote_ref, fetch=True)
|
|
|
|
|
|
- revision = self._AutoFetchRef(options, revision)
|
|
|
|
|
|
+ revision = self._AutoFetchRevision(options, revision)
|
|
|
|
|
|
# This is a big hammer, debatable if it should even be here...
|
|
# This is a big hammer, debatable if it should even be here...
|
|
if options.force or options.reset:
|
|
if options.force or options.reset:
|
|
@@ -573,8 +594,8 @@ class GitWrapper(SCMWrapper):
|
|
# to actually "Clean" the checkout; that commit is uncheckoutable on this
|
|
# to actually "Clean" the checkout; that commit is uncheckoutable on this
|
|
# system. The best we can do is carry forward to the checkout step.
|
|
# system. The best we can do is carry forward to the checkout step.
|
|
if not (options.force or options.reset):
|
|
if not (options.force or options.reset):
|
|
- self._CheckClean(revision)
|
|
|
|
- self._CheckDetachedHead(revision, options)
|
|
|
|
|
|
+ self._CheckClean(revision or ref)
|
|
|
|
+ self._CheckDetachedHead(revision or ref, options)
|
|
if self._Capture(['rev-list', '-n', '1', 'HEAD']) == revision:
|
|
if self._Capture(['rev-list', '-n', '1', 'HEAD']) == revision:
|
|
self.Print('Up-to-date; skipping checkout.')
|
|
self.Print('Up-to-date; skipping checkout.')
|
|
else:
|
|
else:
|
|
@@ -582,43 +603,35 @@ class GitWrapper(SCMWrapper):
|
|
# it only when nuclear options are enabled.
|
|
# it only when nuclear options are enabled.
|
|
self._Checkout(
|
|
self._Checkout(
|
|
options,
|
|
options,
|
|
- revision,
|
|
|
|
|
|
+ revision or ref,
|
|
force=(options.force and options.delete_unversioned_trees),
|
|
force=(options.force and options.delete_unversioned_trees),
|
|
quiet=True,
|
|
quiet=True,
|
|
)
|
|
)
|
|
if not printed_path:
|
|
if not printed_path:
|
|
- self.Print('_____ %s at %s' % (self.relpath, revision), timestamp=False)
|
|
|
|
|
|
+ self.Print('_____ %s at %s' % (self.relpath, revision or ref),
|
|
|
|
+ timestamp=False)
|
|
elif current_type == 'hash':
|
|
elif current_type == 'hash':
|
|
# case 1
|
|
# case 1
|
|
# Can't find a merge-base since we don't know our upstream. That makes
|
|
# Can't find a merge-base since we don't know our upstream. That makes
|
|
# this command VERY likely to produce a rebase failure. For now we
|
|
# this command VERY likely to produce a rebase failure. For now we
|
|
# assume origin is our upstream since that's what the old behavior was.
|
|
# assume origin is our upstream since that's what the old behavior was.
|
|
- upstream_branch = self.remote
|
|
|
|
- if options.revision or deps_revision:
|
|
|
|
- upstream_branch = revision
|
|
|
|
|
|
+ upstream_branch = revision or ref or self.remote
|
|
self._AttemptRebase(upstream_branch, file_list, options,
|
|
self._AttemptRebase(upstream_branch, file_list, options,
|
|
printed_path=printed_path, merge=options.merge)
|
|
printed_path=printed_path, merge=options.merge)
|
|
printed_path = True
|
|
printed_path = True
|
|
- elif rev_type == 'hash':
|
|
|
|
- # case 2
|
|
|
|
- self._AttemptRebase(upstream_branch, file_list, options,
|
|
|
|
- newbase=revision, printed_path=printed_path,
|
|
|
|
- merge=options.merge)
|
|
|
|
- printed_path = True
|
|
|
|
- elif remote_ref and ''.join(remote_ref) != upstream_branch:
|
|
|
|
|
|
+ elif remote_ref and remote_ref != upstream_branch:
|
|
# case 4
|
|
# case 4
|
|
- new_base = ''.join(remote_ref)
|
|
|
|
if not printed_path:
|
|
if not printed_path:
|
|
- self.Print('_____ %s at %s' % (self.relpath, revision), timestamp=False)
|
|
|
|
|
|
+ self.Print('_____ %s at %s' % (self.relpath, ref), timestamp=False)
|
|
switch_error = ("Could not switch upstream branch from %s to %s\n"
|
|
switch_error = ("Could not switch upstream branch from %s to %s\n"
|
|
- % (upstream_branch, new_base) +
|
|
|
|
|
|
+ % (upstream_branch, ref) +
|
|
"Please use --force or merge or rebase manually:\n" +
|
|
"Please use --force or merge or rebase manually:\n" +
|
|
- "cd %s; git rebase %s\n" % (self.checkout_path, new_base) +
|
|
|
|
- "OR git checkout -b <some new branch> %s" % new_base)
|
|
|
|
|
|
+ "cd %s; git rebase %s\n" % (self.checkout_path, ref) +
|
|
|
|
+ "OR git checkout -b <some new branch> %s" % ref)
|
|
force_switch = False
|
|
force_switch = False
|
|
if options.force:
|
|
if options.force:
|
|
try:
|
|
try:
|
|
- self._CheckClean(revision)
|
|
|
|
|
|
+ self._CheckClean(ref)
|
|
# case 4a
|
|
# case 4a
|
|
force_switch = True
|
|
force_switch = True
|
|
except gclient_utils.Error as e:
|
|
except gclient_utils.Error as e:
|
|
@@ -629,15 +642,25 @@ class GitWrapper(SCMWrapper):
|
|
switch_error = '%s\n%s' % (e.message, switch_error)
|
|
switch_error = '%s\n%s' % (e.message, switch_error)
|
|
if force_switch:
|
|
if force_switch:
|
|
self.Print("Switching upstream branch from %s to %s" %
|
|
self.Print("Switching upstream branch from %s to %s" %
|
|
- (upstream_branch, new_base))
|
|
|
|
- switch_branch = 'gclient_' + remote_ref[1]
|
|
|
|
- self._Capture(['branch', '-f', switch_branch, new_base])
|
|
|
|
|
|
+ (upstream_branch, ref))
|
|
|
|
+ switch_branch = 'gclient_' + re.sub('[^A-Za-z0-9]', '_', ref)
|
|
|
|
+ self._Capture(['branch', '-f', switch_branch, ref])
|
|
self._Checkout(options, switch_branch, force=True, quiet=True)
|
|
self._Checkout(options, switch_branch, force=True, quiet=True)
|
|
|
|
+ if revision:
|
|
|
|
+ self._Scrub(revision, options)
|
|
else:
|
|
else:
|
|
# case 4c
|
|
# case 4c
|
|
raise gclient_utils.Error(switch_error)
|
|
raise gclient_utils.Error(switch_error)
|
|
|
|
+ elif revision:
|
|
|
|
+ # case 2
|
|
|
|
+ self._AttemptRebase(upstream_branch, file_list, options,
|
|
|
|
+ newbase=revision, printed_path=printed_path,
|
|
|
|
+ merge=options.merge)
|
|
|
|
+ printed_path = True
|
|
else:
|
|
else:
|
|
# case 3 - the default case
|
|
# case 3 - the default case
|
|
|
|
+ # The same ref as |upstream_branch| was specified, and no revision was
|
|
|
|
+ # used.
|
|
rebase_files = self._GetDiffFilenames(upstream_branch)
|
|
rebase_files = self._GetDiffFilenames(upstream_branch)
|
|
if verbose:
|
|
if verbose:
|
|
self.Print('Trying fast-forward merge to branch : %s' % upstream_branch)
|
|
self.Print('Trying fast-forward merge to branch : %s' % upstream_branch)
|
|
@@ -653,7 +676,7 @@ class GitWrapper(SCMWrapper):
|
|
rebase_files = []
|
|
rebase_files = []
|
|
if re.match('fatal: Not possible to fast-forward, aborting.', e.stderr):
|
|
if re.match('fatal: Not possible to fast-forward, aborting.', e.stderr):
|
|
if not printed_path:
|
|
if not printed_path:
|
|
- self.Print('_____ %s at %s' % (self.relpath, revision),
|
|
|
|
|
|
+ self.Print('_____ %s at %s' % (self.relpath, ref),
|
|
timestamp=False)
|
|
timestamp=False)
|
|
printed_path = True
|
|
printed_path = True
|
|
while True:
|
|
while True:
|
|
@@ -686,7 +709,7 @@ class GitWrapper(SCMWrapper):
|
|
"changes or stash them before you can merge.\n",
|
|
"changes or stash them before you can merge.\n",
|
|
e.stderr):
|
|
e.stderr):
|
|
if not printed_path:
|
|
if not printed_path:
|
|
- self.Print('_____ %s at %s' % (self.relpath, revision),
|
|
|
|
|
|
+ self.Print('_____ %s at %s' % (self.relpath, ref),
|
|
timestamp=False)
|
|
timestamp=False)
|
|
printed_path = True
|
|
printed_path = True
|
|
raise gclient_utils.Error(e.stderr)
|
|
raise gclient_utils.Error(e.stderr)
|
|
@@ -835,13 +858,16 @@ class GitWrapper(SCMWrapper):
|
|
return os.path.join(self._root_dir,
|
|
return os.path.join(self._root_dir,
|
|
'old_' + self.relpath.replace(os.sep, '_')) + '.git'
|
|
'old_' + self.relpath.replace(os.sep, '_')) + '.git'
|
|
|
|
|
|
- def _GetMirror(self, url, options):
|
|
|
|
|
|
+ def _GetMirror(self, url, options, ref=None):
|
|
"""Get a git_cache.Mirror object for the argument url."""
|
|
"""Get a git_cache.Mirror object for the argument url."""
|
|
if not self.cache_dir:
|
|
if not self.cache_dir:
|
|
return None
|
|
return None
|
|
|
|
+ # Don't try to fetch local refs in the mirror.
|
|
|
|
+ if ref and ref.startswith('refs/remotes'):
|
|
|
|
+ ref = None
|
|
mirror_kwargs = {
|
|
mirror_kwargs = {
|
|
'print_func': self.filter,
|
|
'print_func': self.filter,
|
|
- 'refs': []
|
|
|
|
|
|
+ 'refs': [ref] if ref else [],
|
|
}
|
|
}
|
|
if hasattr(options, 'with_branch_heads') and options.with_branch_heads:
|
|
if hasattr(options, 'with_branch_heads') and options.with_branch_heads:
|
|
mirror_kwargs['refs'].append('refs/branch-heads/*')
|
|
mirror_kwargs['refs'].append('refs/branch-heads/*')
|
|
@@ -849,11 +875,11 @@ class GitWrapper(SCMWrapper):
|
|
mirror_kwargs['refs'].append('refs/tags/*')
|
|
mirror_kwargs['refs'].append('refs/tags/*')
|
|
return git_cache.Mirror(url, **mirror_kwargs)
|
|
return git_cache.Mirror(url, **mirror_kwargs)
|
|
|
|
|
|
- def _UpdateMirrorIfNotContains(self, mirror, options, rev_type, revision):
|
|
|
|
|
|
+ def _UpdateMirrorIfNotContains(self, mirror, options, revision):
|
|
"""Update a git mirror by fetching the latest commits from the remote,
|
|
"""Update a git mirror by fetching the latest commits from the remote,
|
|
unless mirror already contains revision whose type is sha1 hash.
|
|
unless mirror already contains revision whose type is sha1 hash.
|
|
"""
|
|
"""
|
|
- if rev_type == 'hash' and mirror.contains_revision(revision):
|
|
|
|
|
|
+ if revision and mirror.contains_revision(revision):
|
|
if options.verbose:
|
|
if options.verbose:
|
|
self.Print('skipping mirror update, it has rev=%s already' % revision,
|
|
self.Print('skipping mirror update, it has rev=%s already' % revision,
|
|
timestamp=False)
|
|
timestamp=False)
|
|
@@ -874,7 +900,7 @@ class GitWrapper(SCMWrapper):
|
|
lock_timeout=getattr(options, 'lock_timeout', 0))
|
|
lock_timeout=getattr(options, 'lock_timeout', 0))
|
|
mirror.unlock()
|
|
mirror.unlock()
|
|
|
|
|
|
- def _Clone(self, revision, url, options):
|
|
|
|
|
|
+ def _Clone(self, ref, remote_ref, revision, url, options):
|
|
"""Clone a git repository from the given URL.
|
|
"""Clone a git repository from the given URL.
|
|
|
|
|
|
Once we've cloned the repo, we checkout a working branch if the specified
|
|
Once we've cloned the repo, we checkout a working branch if the specified
|
|
@@ -900,7 +926,7 @@ class GitWrapper(SCMWrapper):
|
|
|
|
|
|
template_dir = None
|
|
template_dir = None
|
|
if hasattr(options, 'no_history') and options.no_history:
|
|
if hasattr(options, 'no_history') and options.no_history:
|
|
- if gclient_utils.IsGitSha(revision):
|
|
|
|
|
|
+ if revision and gclient_utils.IsGitSha(revision):
|
|
# In the case of a subproject, the pinned sha is not necessarily the
|
|
# In the case of a subproject, the pinned sha is not necessarily the
|
|
# head of the remote branch (so we can't just use --depth=N). Instead,
|
|
# head of the remote branch (so we can't just use --depth=N). Instead,
|
|
# we tell git to fetch all the remote objects from SHA..HEAD by means of
|
|
# we tell git to fetch all the remote objects from SHA..HEAD by means of
|
|
@@ -941,17 +967,18 @@ class GitWrapper(SCMWrapper):
|
|
gclient_utils.rmtree(tmp_dir)
|
|
gclient_utils.rmtree(tmp_dir)
|
|
if template_dir:
|
|
if template_dir:
|
|
gclient_utils.rmtree(template_dir)
|
|
gclient_utils.rmtree(template_dir)
|
|
- self._UpdateBranchHeads(options, fetch=True)
|
|
|
|
- revision = self._AutoFetchRef(options, revision)
|
|
|
|
- remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote)
|
|
|
|
- self._Checkout(options, ''.join(remote_ref or revision), quiet=True)
|
|
|
|
|
|
+ self._UpdateBranchHeads(options, ref, remote_ref, fetch=True)
|
|
|
|
+ if revision:
|
|
|
|
+ revision = self._AutoFetchRevision(options, revision)
|
|
|
|
+ self._Checkout(options, revision or remote_ref, quiet=True)
|
|
if self._GetCurrentBranch() is None:
|
|
if self._GetCurrentBranch() is None:
|
|
# Squelch git's very verbose detached HEAD warning and use our own
|
|
# Squelch git's very verbose detached HEAD warning and use our own
|
|
self.Print(
|
|
self.Print(
|
|
('Checked out %s to a detached HEAD. Before making any commits\n'
|
|
('Checked out %s to a detached HEAD. Before making any commits\n'
|
|
'in this repo, you should use \'git checkout <branch>\' to switch to\n'
|
|
'in this repo, you should use \'git checkout <branch>\' to switch to\n'
|
|
'an existing branch or use \'git checkout %s -b <branch>\' to\n'
|
|
'an existing branch or use \'git checkout %s -b <branch>\' to\n'
|
|
- 'create a new branch for your work.') % (revision, self.remote))
|
|
|
|
|
|
+ 'create a new branch for your work.') % (
|
|
|
|
+ revision or remote_ref, self.remote))
|
|
|
|
|
|
def _AskForData(self, prompt, options):
|
|
def _AskForData(self, prompt, options):
|
|
if options.jobs > 1:
|
|
if options.jobs > 1:
|
|
@@ -1051,7 +1078,8 @@ class GitWrapper(SCMWrapper):
|
|
raise gclient_utils.Error('git version %s < minimum required %s' %
|
|
raise gclient_utils.Error('git version %s < minimum required %s' %
|
|
(current_version, min_version))
|
|
(current_version, min_version))
|
|
|
|
|
|
- def _EnsureValidHeadObjectOrCheckout(self, revision, options, url):
|
|
|
|
|
|
+ def _EnsureValidHeadObjectOrCheckout(self, ref, remote_ref, revision, options,
|
|
|
|
+ url):
|
|
# Special case handling if all 3 conditions are met:
|
|
# Special case handling if all 3 conditions are met:
|
|
# * the mirros have recently changed, but deps destination remains same,
|
|
# * the mirros have recently changed, but deps destination remains same,
|
|
# * the git histories of mirrors are conflicting.
|
|
# * the git histories of mirrors are conflicting.
|
|
@@ -1070,7 +1098,7 @@ class GitWrapper(SCMWrapper):
|
|
'%s' % e)
|
|
'%s' % e)
|
|
)
|
|
)
|
|
self._DeleteOrMove(options.force)
|
|
self._DeleteOrMove(options.force)
|
|
- self._Clone(revision, url, options)
|
|
|
|
|
|
+ self._Clone(ref, remote_ref, revision, url, options)
|
|
else:
|
|
else:
|
|
raise
|
|
raise
|
|
|
|
|
|
@@ -1170,6 +1198,7 @@ class GitWrapper(SCMWrapper):
|
|
if quiet:
|
|
if quiet:
|
|
checkout_args.append('--quiet')
|
|
checkout_args.append('--quiet')
|
|
checkout_args.append(ref)
|
|
checkout_args.append(ref)
|
|
|
|
+ checkout_args.append('--')
|
|
return self._Capture(checkout_args)
|
|
return self._Capture(checkout_args)
|
|
|
|
|
|
def _Fetch(self, options, remote=None, prune=False, quiet=False,
|
|
def _Fetch(self, options, remote=None, prune=False, quiet=False,
|
|
@@ -1204,7 +1233,7 @@ class GitWrapper(SCMWrapper):
|
|
# Return the revision that was fetched; this will be stored in 'FETCH_HEAD'
|
|
# Return the revision that was fetched; this will be stored in 'FETCH_HEAD'
|
|
return self._Capture(['rev-parse', '--verify', 'FETCH_HEAD'])
|
|
return self._Capture(['rev-parse', '--verify', 'FETCH_HEAD'])
|
|
|
|
|
|
- def _UpdateBranchHeads(self, options, fetch=False):
|
|
|
|
|
|
+ def _UpdateBranchHeads(self, options, ref, remote_ref, fetch=False):
|
|
"""Adds, and optionally fetches, "branch-heads" and "tags" refspecs
|
|
"""Adds, and optionally fetches, "branch-heads" and "tags" refspecs
|
|
if requested."""
|
|
if requested."""
|
|
need_fetch = fetch
|
|
need_fetch = fetch
|
|
@@ -1220,16 +1249,20 @@ class GitWrapper(SCMWrapper):
|
|
'^\\+refs/tags/\\*:.*$']
|
|
'^\\+refs/tags/\\*:.*$']
|
|
self._Run(config_cmd, options)
|
|
self._Run(config_cmd, options)
|
|
need_fetch = True
|
|
need_fetch = True
|
|
|
|
+ # Make sure we fetch the ref we're asked to sync, if any.
|
|
|
|
+ if ref and not ref.startswith(('refs/remotes',)):
|
|
|
|
+ config_cmd = ['config', 'remote.%s.fetch' % self.remote,
|
|
|
|
+ '+%s:%s' % (ref, remote_ref), '--add']
|
|
|
|
+ self._Run(config_cmd, options)
|
|
|
|
+ need_fetch = True
|
|
if fetch and need_fetch:
|
|
if fetch and need_fetch:
|
|
self._Fetch(options, prune=options.force)
|
|
self._Fetch(options, prune=options.force)
|
|
|
|
|
|
- def _AutoFetchRef(self, options, revision):
|
|
|
|
|
|
+ def _AutoFetchRevision(self, options, revision):
|
|
"""Attempts to fetch |revision| if not available in local repo.
|
|
"""Attempts to fetch |revision| if not available in local repo.
|
|
|
|
|
|
Returns possibly updated revision."""
|
|
Returns possibly updated revision."""
|
|
- try:
|
|
|
|
- self._Capture(['rev-parse', revision])
|
|
|
|
- except subprocess2.CalledProcessError:
|
|
|
|
|
|
+ if revision and not scm.GIT.IsValidRevision(self.checkout_path, revision):
|
|
self._Fetch(options, refspec=revision)
|
|
self._Fetch(options, refspec=revision)
|
|
revision = self._Capture(['rev-parse', 'FETCH_HEAD'])
|
|
revision = self._Capture(['rev-parse', 'FETCH_HEAD'])
|
|
return revision
|
|
return revision
|