| Index: gclient_scm.py
|
| diff --git a/gclient_scm.py b/gclient_scm.py
|
| index 8236282af161639ee6d4e194c63dce29f8c4043d..7bf559c5083c71f7223d7f3e5204272afa41a789 100644
|
| --- a/gclient_scm.py
|
| +++ b/gclient_scm.py
|
| @@ -369,11 +369,14 @@ class GitWrapper(SCMWrapper):
|
| verbose = ['--verbose']
|
| printed_path = True
|
|
|
| - if revision.startswith('refs/'):
|
| - rev_type = "branch"
|
| - elif revision.startswith(self.remote + '/'):
|
| + remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote)
|
| + if remote_ref:
|
| # Rewrite remote refs to their local equivalents.
|
| - revision = 'refs/remotes/' + revision
|
| + 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
|
| @@ -393,10 +396,6 @@ class GitWrapper(SCMWrapper):
|
| except subprocess2.CalledProcessError:
|
| self._DeleteOrMove(options.force)
|
| self._Clone(revision, url, options)
|
| - if deps_revision and deps_revision.startswith('branch-heads/'):
|
| - deps_branch = deps_revision.replace('branch-heads/', '')
|
| - self._Capture(['branch', deps_branch, deps_revision])
|
| - self._Checkout(options, deps_branch, quiet=True)
|
| if file_list is not None:
|
| files = self._Capture(['ls-files']).splitlines()
|
| file_list.extend([os.path.join(self.checkout_path, f) for f in files])
|
| @@ -451,12 +450,16 @@ class GitWrapper(SCMWrapper):
|
| # 2) current branch is tracking a remote branch with local committed
|
| # changes, but the DEPS file switched to point to a hash
|
| # - rebase those changes on top of the hash
|
| - # 3) current branch is tracking a remote branch w/or w/out changes,
|
| - # no switch
|
| + # 3) current branch is tracking a remote branch w/or w/out changes, and
|
| + # no DEPS switch
|
| # - see if we can FF, if not, prompt the user for rebase, merge, or stop
|
| - # 4) current branch is tracking a remote branch, switches to a different
|
| - # remote branch
|
| - # - exit
|
| + # 4) current branch is tracking a remote branch, but DEPS switches to a
|
| + # different remote branch, and
|
| + # a) current branch has no local changes, and --force:
|
| + # - checkout new branch
|
| + # b) current branch has local changes, and --force and --reset:
|
| + # - checkout new branch
|
| + # c) otherwise exit
|
|
|
| # GetUpstreamBranch returns something like 'refs/remotes/origin/master' for
|
| # a tracking branch
|
| @@ -534,17 +537,37 @@ class GitWrapper(SCMWrapper):
|
| newbase=revision, printed_path=printed_path,
|
| merge=options.merge)
|
| printed_path = True
|
| - elif revision.replace('heads', 'remotes/' + self.remote) != upstream_branch:
|
| + elif remote_ref and ''.join(remote_ref) != upstream_branch:
|
| # case 4
|
| - new_base = revision.replace('heads', 'remotes/' + self.remote)
|
| + new_base = ''.join(remote_ref)
|
| if not printed_path:
|
| self.Print('_____ %s%s' % (self.relpath, rev_str), timestamp=False)
|
| - switch_error = ("Switching upstream branch from %s to %s\n"
|
| + switch_error = ("Could not switch upstream branch from %s to %s\n"
|
| % (upstream_branch, new_base) +
|
| - "Please 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)
|
| - raise gclient_utils.Error(switch_error)
|
| + force_switch = False
|
| + if options.force:
|
| + try:
|
| + self._CheckClean(rev_str)
|
| + # case 4a
|
| + force_switch = True
|
| + except gclient_utils.Error as e:
|
| + if options.reset:
|
| + # case 4b
|
| + force_switch = True
|
| + else:
|
| + switch_error = '%s\n%s' % (e.message, switch_error)
|
| + if force_switch:
|
| + 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])
|
| + self._Checkout(options, switch_branch, force=True, quiet=True)
|
| + else:
|
| + # case 4c
|
| + raise gclient_utils.Error(switch_error)
|
| else:
|
| # case 3 - the default case
|
| if files is not None:
|
| @@ -870,7 +893,8 @@ class GitWrapper(SCMWrapper):
|
| if template_dir:
|
| gclient_utils.rmtree(template_dir)
|
| self._UpdateBranchHeads(options, fetch=True)
|
| - self._Checkout(options, revision.replace('refs/heads/', ''), quiet=True)
|
| + remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote)
|
| + self._Checkout(options, ''.join(remote_ref or revision), quiet=True)
|
| if self._GetCurrentBranch() is None:
|
| # Squelch git's very verbose detached HEAD warning and use our own
|
| self.Print(
|
|
|