gclient: Add support for the branch:revision format.

Bug: 850812, 853032
Change-Id: I597acbde2b3c229813b7eba8fcba52d5877130b2
Reviewed-on: https://chromium-review.googlesource.com/1119235
Commit-Queue: Edward Lesmes <ehmaldonado@chromium.org>
Reviewed-by: Aaron Gable <agable@chromium.org>
changes/35/1119235/7
Edward Lemur 7 years ago committed by Commit Bot
parent 8a2e331aa7
commit d328b47eb1

@ -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. # If a dependency is not pinned, track refs/heads/master by default.
default_rev = 'refs/remotes/%s/master' % self.remote 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) ref = remote_ref = None
if remote_ref: # Support the 'branch:revision' syntax.
# Rewrite remote refs to their local equivalents. if ':' in revision:
revision = ''.join(remote_ref) ref, revision = revision.split(':')
rev_type = "branch" if not gclient_utils.IsFullGitSha(revision):
elif revision.startswith('refs/'): raise gclient_utils.Error(
# Local branch? We probably don't want to support, since DEPS should 'Invalid format: %s:%s. revision must be a git hash.' % (
# always specify branches as they are in the upstream repo. remote_ref, revision))
rev_type = "branch" elif not gclient_utils.IsFullGitSha(revision):
else: ref = revision
# hash is also a tag, only make a distinction at checkout revision = None
rev_type = "hash"
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._EnsureValidHeadObjectOrCheckout(ref, remote_ref, revision, options,
self._FetchAndReset(revision, file_list, 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._CheckClean(revision or ref)
self._CheckDetachedHead(revision, options) 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 upstream_branch = revision or ref or self.remote
if options.revision or deps_revision:
upstream_branch = revision
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': elif remote_ref and remote_ref != upstream_branch:
# 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:
# 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) + "cd %s; git rebase %s\n" % (self.checkout_path, ref) +
"OR git checkout -b <some new branch> %s" % new_base) "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)) (upstream_branch, ref))
switch_branch = 'gclient_' + remote_ref[1] switch_branch = 'gclient_' + re.sub('[^A-Za-z0-9]', '_', ref)
self._Capture(['branch', '-f', switch_branch, new_base]) 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) self._UpdateBranchHeads(options, ref, remote_ref, fetch=True)
revision = self._AutoFetchRef(options, revision) if revision:
remote_ref = scm.GIT.RefToRemoteRef(revision, self.remote) revision = self._AutoFetchRevision(options, revision)
self._Checkout(options, ''.join(remote_ref or revision), quiet=True) 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: if revision and not scm.GIT.IsValidRevision(self.checkout_path, revision):
self._Capture(['rev-parse', revision])
except subprocess2.CalledProcessError:
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

@ -382,10 +382,8 @@ deps_os = {
}""" % { }""" % {
'git_base': self.git_base, 'git_base': self.git_base,
# See self.__init__() for the format. Grab's the hash of the first # See self.__init__() for the format. Grab's the hash of the first
# commit in repo_2. Only keep the first 7 character because of: # commit in repo_3.
# TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. 'hash3': self.git_hashes['repo_3'][1][0]
# duh.
'hash3': self.git_hashes['repo_3'][1][0][:7]
}, },
'origin': 'git/repo_1@1\n', 'origin': 'git/repo_1@1\n',
}) })
@ -446,9 +444,8 @@ hooks = [
""" % { """ % {
'git_base': self.git_base, 'git_base': self.git_base,
# See self.__init__() for the format. Grab's the hash of the first # See self.__init__() for the format. Grab's the hash of the first
# commit in repo_2. Only keep the first 7 character because of: # commit in repo_2.
# TODO(maruel): http://crosbug.com/3591 We need to strip the hash.. duh. 'hash': self.git_hashes['repo_2'][1][0]
'hash': self.git_hashes['repo_2'][1][0][:7]
}, },
'origin': 'git/repo_1@2\n', 'origin': 'git/repo_1@2\n',
}) })
@ -471,8 +468,8 @@ pre_deps_hooks = [
] ]
""" % { """ % {
'git_base': self.git_base, 'git_base': self.git_base,
'hash1': self.git_hashes['repo_1'][2][0][:7], 'hash1': self.git_hashes['repo_1'][2][0],
'hash2': self.git_hashes['repo_2'][1][0][:7], 'hash2': self.git_hashes['repo_2'][1][0],
}, },
'origin': 'git/repo_5@2\n', 'origin': 'git/repo_5@2\n',
}) })
@ -496,8 +493,8 @@ pre_deps_hooks = [
] ]
""" % { """ % {
'git_base': self.git_base, 'git_base': self.git_base,
'hash1': self.git_hashes['repo_1'][2][0][:7], 'hash1': self.git_hashes['repo_1'][2][0],
'hash2': self.git_hashes['repo_2'][1][0][:7], 'hash2': self.git_hashes['repo_2'][1][0],
}, },
'origin': 'git/repo_5@3\n', 'origin': 'git/repo_5@3\n',
}) })
@ -594,7 +591,7 @@ recursedeps = [
'src/repo8', 'src/repo8',
]""" % { ]""" % {
'git_base': self.git_base, 'git_base': self.git_base,
'hash': self.git_hashes['repo_2'][1][0][:7] 'hash': self.git_hashes['repo_2'][1][0]
}, },
'origin': 'git/repo_6@1\n', 'origin': 'git/repo_6@1\n',
}) })
@ -638,7 +635,7 @@ deps_os ={
vars = { vars = {
'str_var': 'xyz', 'str_var': 'xyz',
} }
gclient_gn_args_file = 'src/repo2/gclient.args' gclient_gn_args_file = 'src/repo9/gclient.args'
gclient_gn_args = [ gclient_gn_args = [
'str_var', 'str_var',
] ]

@ -184,6 +184,20 @@ Add C
from :3 from :3
M 100644 :7 c M 100644 :7 c
blob
mark :9
data 4
foo
commit refs/heads/feature
mark :10
author Alice <alice@example.com> 1490311986 -0700
committer Alice <alice@example.com> 1490311986 -0700
data 6
Add D
from :8
M 100644 :9 d
reset refs/heads/master reset refs/heads/master
from :3 from :3
""" """
@ -213,7 +227,8 @@ from :3
stderr=STDOUT, cwd=path).communicate() stderr=STDOUT, cwd=path).communicate()
Popen(['git', 'checkout', '-b', 'new', 'origin/master', '-q'], stdout=PIPE, Popen(['git', 'checkout', '-b', 'new', 'origin/master', '-q'], stdout=PIPE,
stderr=STDOUT, cwd=path).communicate() stderr=STDOUT, cwd=path).communicate()
Popen(['git', 'push', 'origin', 'origin/origin:origin/master', '-q'], Popen(['git', 'push', 'origin',
'refs/heads/origin:refs/heads/master', '-q'],
stdout=PIPE, stderr=STDOUT, cwd=path).communicate() stdout=PIPE, stderr=STDOUT, cwd=path).communicate()
Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE, Popen(['git', 'config', '--unset', 'remote.origin.fetch'], stdout=PIPE,
stderr=STDOUT, cwd=path).communicate() stderr=STDOUT, cwd=path).communicate()
@ -383,6 +398,21 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
'a7142dc9f0009350b96a11f372b6ea658592aa95') 'a7142dc9f0009350b96a11f372b6ea658592aa95')
sys.stdout.close() sys.stdout.close()
def testUpdateRefRevision(self):
if not self.enabled:
return
options = self.Options()
options.force = True
options.revision = ('refs/heads/feature'
':9a51244740b25fa2ded5252ca00a3178d3f665a9')
scm = gclient_scm.GitWrapper(self.url, self.root_dir,
self.relpath)
file_list = []
scm.update(options, (), file_list)
self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9')
sys.stdout.close()
def testUpdateMerge(self): def testUpdateMerge(self):
if not self.enabled: if not self.enabled:
return return
@ -395,11 +425,11 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
file_list = [] file_list = []
scm.update(options, (), file_list) scm.update(options, (), file_list)
self.assertEquals(file_list, [join(self.base_path, x) self.assertEquals(file_list, [join(self.base_path, x)
for x in ['a', 'b', 'c']]) for x in ['a', 'b', 'c', 'd']])
# The actual commit that is created is unstable, so we verify its tree and # The actual commit that is created is unstable, so we verify its tree and
# parents instead. # parents instead.
self.assertEquals(scm._Capture(['rev-parse', 'HEAD:']), self.assertEquals(scm._Capture(['rev-parse', 'HEAD:']),
'd2e35c10ac24d6c621e14a1fcadceb533155627d') 'f7c1b0aaff248edf8981c776dcf6014c3eb09936')
self.assertEquals(scm._Capture(['rev-parse', 'HEAD^1']), rev) self.assertEquals(scm._Capture(['rev-parse', 'HEAD^1']), rev)
self.assertEquals(scm._Capture(['rev-parse', 'HEAD^2']), self.assertEquals(scm._Capture(['rev-parse', 'HEAD^2']),
scm._Capture(['rev-parse', 'origin/master'])) scm._Capture(['rev-parse', 'origin/master']))
@ -419,12 +449,12 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
'(y)es / (q)uit / (s)kip : ', 'y') '(y)es / (q)uit / (s)kip : ', 'y')
scm.update(options, (), file_list) scm.update(options, (), file_list)
self.assertEquals(file_list, [join(self.base_path, x) self.assertEquals(file_list, [join(self.base_path, x)
for x in ['a', 'b', 'c']]) for x in "abcd"])
# The actual commit that is created is unstable, so we verify its tree and # The actual commit that is created is unstable, so we verify its tree and
# parent instead. # parent instead.
self.assertEquals(scm._Capture(['rev-parse', 'HEAD:']), self.assertEquals(scm._Capture(['rev-parse', 'HEAD:']),
'd2e35c10ac24d6c621e14a1fcadceb533155627d') 'f7c1b0aaff248edf8981c776dcf6014c3eb09936')
self.assertEquals(scm._Capture(['rev-parse', 'HEAD^']), self.assertEquals(scm._Capture(['rev-parse', 'HEAD^^']),
scm._Capture(['rev-parse', 'origin/master'])) scm._Capture(['rev-parse', 'origin/master']))
sys.stdout.close() sys.stdout.close()
@ -537,7 +567,7 @@ class ManagedGitWrapperTestCase(BaseGitWrapperTestCase):
'Fix the conflict and run gclient again.\n' 'Fix the conflict and run gclient again.\n'
'See \'man git-rebase\' for details.\n') 'See \'man git-rebase\' for details.\n')
self.assertRaisesError(exception, scm.update, options, (), []) self.assertRaisesError(exception, scm.update, options, (), [])
exception = ('\n____ . at refs/remotes/origin/master\n' exception = ('\n____ . at refs/heads/master\n'
'\tYou have unstaged changes.\n' '\tYou have unstaged changes.\n'
'\tPlease commit, stash, or reset.\n') '\tPlease commit, stash, or reset.\n')
self.assertRaisesError(exception, scm.update, options, (), []) self.assertRaisesError(exception, scm.update, options, (), [])
@ -635,8 +665,9 @@ class ManagedGitWrapperTestCaseMox(BaseTestCase):
).AndReturn(False) ).AndReturn(False)
self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_Clone', True) self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_Clone', True)
# pylint: disable=no-value-for-parameter # pylint: disable=no-value-for-parameter
gclient_scm.GitWrapper._Clone('refs/remotes/origin/master', self.url, gclient_scm.GitWrapper._Clone(
options) 'refs/heads/master', 'refs/remotes/origin/master', None, self.url,
options)
self.mox.StubOutWithMock(gclient_scm.subprocess2, 'check_output', True) self.mox.StubOutWithMock(gclient_scm.subprocess2, 'check_output', True)
gclient_scm.subprocess2.check_output( gclient_scm.subprocess2.check_output(
['git', '-c', 'core.quotePath=false', 'ls-files'], cwd=self.base_path, ['git', '-c', 'core.quotePath=false', 'ls-files'], cwd=self.base_path,
@ -667,13 +698,15 @@ class ManagedGitWrapperTestCaseMox(BaseTestCase):
self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_Clone', True) self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_Clone', True)
# pylint: disable=no-value-for-parameter # pylint: disable=no-value-for-parameter
gclient_scm.GitWrapper._Clone( gclient_scm.GitWrapper._Clone(
'refs/remotes/origin/master', self.url, options 'refs/heads/master', 'refs/remotes/origin/master', None, self.url,
options
).AndRaise(gclient_scm.subprocess2.CalledProcessError(None, None, None, ).AndRaise(gclient_scm.subprocess2.CalledProcessError(None, None, None,
None, None)) None, None))
self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_DeleteOrMove', True) self.mox.StubOutWithMock(gclient_scm.GitWrapper, '_DeleteOrMove', True)
gclient_scm.GitWrapper._DeleteOrMove(False) gclient_scm.GitWrapper._DeleteOrMove(False)
gclient_scm.GitWrapper._Clone('refs/remotes/origin/master', self.url, gclient_scm.GitWrapper._Clone(
options) 'refs/heads/master', 'refs/remotes/origin/master', None, self.url,
options)
self.mox.StubOutWithMock(gclient_scm.subprocess2, 'check_output', True) self.mox.StubOutWithMock(gclient_scm.subprocess2, 'check_output', True)
gclient_scm.subprocess2.check_output( gclient_scm.subprocess2.check_output(
['git', '-c', 'core.quotePath=false', 'ls-files'], cwd=self.base_path, ['git', '-c', 'core.quotePath=false', 'ls-files'], cwd=self.base_path,
@ -735,7 +768,7 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
self.assertEquals(file_list, expected_file_list) self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None), self.assertEquals(scm.revinfo(options, (), None),
'069c602044c5388d2d15c3f875b057c852003458') 'a7142dc9f0009350b96a11f372b6ea658592aa95')
# indicates detached HEAD # indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None) self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout( self.checkInStdout(
@ -743,6 +776,33 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
rmtree(origin_root_dir) rmtree(origin_root_dir)
def testUpdateCloneRefRevision(self):
if not self.enabled:
return
options = self.Options()
options.revision = ('refs/heads/feature'
':9a51244740b25fa2ded5252ca00a3178d3f665a9')
origin_root_dir = self.root_dir
self.root_dir = tempfile.mkdtemp()
self.relpath = '.'
self.base_path = join(self.root_dir, self.relpath)
scm = gclient_scm.GitWrapper(origin_root_dir,
self.root_dir,
self.relpath)
file_list = []
scm.update(options, (), file_list)
self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9')
# indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout(
'Checked out 9a51244740b25fa2ded5252ca00a3178d3f665a9 to a detached HEAD')
rmtree(origin_root_dir)
def testUpdateCloneOnCommit(self): def testUpdateCloneOnCommit(self):
if not self.enabled: if not self.enabled:
return return
@ -792,18 +852,19 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
expected_file_list = [join(self.base_path, "a"), expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b"), join(self.base_path, "b"),
join(self.base_path, "c")] join(self.base_path, "c"),
join(self.base_path, "d")]
file_list = [] file_list = []
options.revision = 'unmanaged' options.revision = 'unmanaged'
scm.update(options, (), file_list) scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list) self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None), self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9') '8980cdcc0b037755eec87c47f1a9d7e90d580015')
# indicates detached HEAD # indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None) self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout( self.checkInStdout(
'Checked out 9a51244740b25fa2ded5252ca00a3178d3f665a9 ' 'Checked out refs/remotes/origin/feature '
'to a detached HEAD') 'to a detached HEAD')
rmtree(origin_root_dir) rmtree(origin_root_dir)
@ -825,14 +886,15 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
expected_file_list = [join(self.base_path, "a"), expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b"), join(self.base_path, "b"),
join(self.base_path, "c")] join(self.base_path, "c"),
join(self.base_path, "d")]
file_list = [] file_list = []
options.revision = 'unmanaged' options.revision = 'unmanaged'
scm.update(options, (), file_list) scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list) self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None), self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9') '8980cdcc0b037755eec87c47f1a9d7e90d580015')
# indicates detached HEAD # indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None) self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout( self.checkInStdout(
@ -857,15 +919,16 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
expected_file_list = [join(self.base_path, "a"), expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b"), join(self.base_path, "b"),
join(self.base_path, "c")] join(self.base_path, "c"),
join(self.base_path, "d")]
file_list = [] file_list = []
options.revision = 'unmanaged' options.revision = 'unmanaged'
scm.update(options, (), file_list) scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list) self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None), self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9') '8980cdcc0b037755eec87c47f1a9d7e90d580015')
# @refs/heads/feature is AKA @refs/remotes/origin/feature in the clone, so # @refs/heads/feature is AKA @refs/heads/feature in the clone, so
# should be treated as such by gclient. # should be treated as such by gclient.
# TODO(mmoss): Though really, we should only allow DEPS to specify branches # TODO(mmoss): Though really, we should only allow DEPS to specify branches
# as they are known in the upstream repo, since the mapping into the local # as they are known in the upstream repo, since the mapping into the local

@ -39,7 +39,7 @@ class GClientSmokeBase(fake_repos.FakeReposTestBase):
self.env['DEPOT_TOOLS_UPDATE'] = '0' self.env['DEPOT_TOOLS_UPDATE'] = '0'
self.env['DEPOT_TOOLS_METRICS'] = '0' self.env['DEPOT_TOOLS_METRICS'] = '0'
def gclient(self, cmd, cwd=None): def gclient(self, cmd, cwd=None, ignore_errors=False):
if not cwd: if not cwd:
cwd = self.root_dir cwd = self.root_dir
if COVERAGE: if COVERAGE:
@ -54,6 +54,8 @@ class GClientSmokeBase(fake_repos.FakeReposTestBase):
(stdout, stderr) = process.communicate() (stdout, stderr) = process.communicate()
logging.debug("XXX: %s\n%s\nXXX" % (' '.join(cmd), stdout)) logging.debug("XXX: %s\n%s\nXXX" % (' '.join(cmd), stdout))
logging.debug("YYY: %s\n%s\nYYY" % (' '.join(cmd), stderr)) logging.debug("YYY: %s\n%s\nYYY" % (' '.join(cmd), stderr))
if process.returncode and not ignore_errors:
raise subprocess.CalledProcessError(process.returncode, cmd, stdout)
return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'), return (stdout.replace('\r\n', '\n'), stderr.replace('\r\n', '\n'),
process.returncode) process.returncode)
@ -158,14 +160,14 @@ class GClientSmoke(GClientSmokeBase):
def testNotConfigured(self): def testNotConfigured(self):
res = ('', 'Error: client not configured; see \'gclient config\'\n', 1) res = ('', 'Error: client not configured; see \'gclient config\'\n', 1)
self.check(res, self.gclient(['diff'])) self.check(res, self.gclient(['diff'], ignore_errors=True))
self.check(res, self.gclient(['pack'])) self.check(res, self.gclient(['pack'], ignore_errors=True))
self.check(res, self.gclient(['revert'])) self.check(res, self.gclient(['revert'], ignore_errors=True))
self.check(res, self.gclient(['revinfo'])) self.check(res, self.gclient(['revinfo'], ignore_errors=True))
self.check(res, self.gclient(['runhooks'])) self.check(res, self.gclient(['runhooks'], ignore_errors=True))
self.check(res, self.gclient(['status'])) self.check(res, self.gclient(['status'], ignore_errors=True))
self.check(res, self.gclient(['sync'])) self.check(res, self.gclient(['sync'], ignore_errors=True))
self.check(res, self.gclient(['update'])) self.check(res, self.gclient(['update'], ignore_errors=True))
def testConfig(self): def testConfig(self):
# Get any bootstrapping out of the way. # Get any bootstrapping out of the way.
@ -249,7 +251,7 @@ class GClientSmoke(GClientSmokeBase):
test(['config', '--spec', '["blah blah"]'], '["blah blah"]') test(['config', '--spec', '["blah blah"]'], '["blah blah"]')
os.remove(p) os.remove(p)
results = self.gclient(['config', 'foo', 'faa', 'fuu']) results = self.gclient(['config', 'foo', 'faa', 'fuu'], ignore_errors=True)
err = ('Usage: gclient.py config [options] [url]\n\n' err = ('Usage: gclient.py config [options] [url]\n\n'
'gclient.py: error: Inconsistent arguments. Use either --spec or one' 'gclient.py: error: Inconsistent arguments. Use either --spec or one'
' or 2 args\n') ' or 2 args\n')
@ -381,7 +383,7 @@ class GClientSmokeGIT(GClientSmokeBase):
'src/repo2/': { 'src/repo2/': {
'scm': 'git', 'scm': 'git',
'url': 'url':
self.git_base + 'repo_2@' + self.githash('repo_2', 1)[:7], self.git_base + 'repo_2@' + self.githash('repo_2', 1),
'revision': self.githash('repo_2', 1), 'revision': self.githash('repo_2', 1),
'was_processed': True, 'was_processed': True,
}, },
@ -724,7 +726,8 @@ class GClientSmokeGIT(GClientSmokeBase):
% (sys.executable, self.root_dir)) % (sys.executable, self.root_dir))
stdout, stderr, retcode = self.gclient(['sync', '--deps', 'mac', '--jobs=1', stdout, stderr, retcode = self.gclient(['sync', '--deps', 'mac', '--jobs=1',
'--revision', '--revision',
'src@' + self.githash('repo_5', 3)]) 'src@' + self.githash('repo_5', 3)],
ignore_errors=True)
self.assertEquals(stderr, expected_stderr) self.assertEquals(stderr, expected_stderr)
self.assertEquals(2, retcode) self.assertEquals(2, retcode)
self.checkBlock(stdout, expectated_stdout) self.checkBlock(stdout, expectated_stdout)
@ -740,7 +743,7 @@ class GClientSmokeGIT(GClientSmokeBase):
'src/repo2/repo_renamed: %(base)srepo_3\n' % 'src/repo2/repo_renamed: %(base)srepo_3\n' %
{ {
'base': self.git_base, 'base': self.git_base,
'hash2': self.githash('repo_2', 1)[:7], 'hash2': self.githash('repo_2', 1),
}) })
self.check((out, '', 0), results) self.check((out, '', 0), results)
@ -783,7 +786,7 @@ class GClientSmokeGIT(GClientSmokeBase):
out = ('src/repo2: %(base)srepo_2@%(hash2)s\n' % out = ('src/repo2: %(base)srepo_2@%(hash2)s\n' %
{ {
'base': self.git_base, 'base': self.git_base,
'hash2': self.githash('repo_2', 1)[:7], 'hash2': self.githash('repo_2', 1),
}) })
self.check((out, '', 0), results) self.check((out, '', 0), results)
@ -798,7 +801,7 @@ class GClientSmokeGIT(GClientSmokeBase):
'src/repo2: %(base)srepo_2@%(hash2)s\n' % 'src/repo2: %(base)srepo_2@%(hash2)s\n' %
{ {
'base': self.git_base, 'base': self.git_base,
'hash2': self.githash('repo_2', 1)[:7], 'hash2': self.githash('repo_2', 1),
}) })
self.check((out, '', 0), results) self.check((out, '', 0), results)
@ -819,7 +822,7 @@ class GClientSmokeGIT(GClientSmokeBase):
}, },
'src/repo2': { 'src/repo2': {
'url': self.git_base + 'repo_2', 'url': self.git_base + 'repo_2',
'rev': self.githash('repo_2', 1)[:7], 'rev': self.githash('repo_2', 1),
}, },
'src/repo2/repo_renamed': { 'src/repo2/repo_renamed': {
'url': self.git_base + 'repo_3', 'url': self.git_base + 'repo_3',
@ -987,7 +990,7 @@ class GClientSmokeGIT(GClientSmokeBase):
' # src -> src/repo2', ' # src -> src/repo2',
' "src/repo2": {', ' "src/repo2": {',
' "url": "' + self.git_base + 'repo_2@%s",' % ( ' "url": "' + self.git_base + 'repo_2@%s",' % (
self.githash('repo_2', 1)[:7]), self.githash('repo_2', 1)),
' "condition": \'true_str_var\',', ' "condition": \'true_str_var\',',
' },', ' },',
'', '',
@ -1093,7 +1096,7 @@ class GClientSmokeGIT(GClientSmokeBase):
'}', '}',
'', '',
'# ' + self.git_base + 'repo_2@%s, DEPS' % ( '# ' + self.git_base + 'repo_2@%s, DEPS' % (
self.githash('repo_2', 1)[:7]), self.githash('repo_2', 1)),
'# ' + self.git_base + 'repo_6, DEPS', '# ' + self.git_base + 'repo_6, DEPS',
'# ' + self.git_base + 'repo_8, DEPS', '# ' + self.git_base + 'repo_8, DEPS',
], deps_contents.splitlines()) ], deps_contents.splitlines())
@ -1291,7 +1294,7 @@ class GClientSmokeGIT(GClientSmokeBase):
self.maxDiff = None self.maxDiff = None
self.assertEqual([ self.assertEqual([
'gclient_gn_args_file = "src/repo2/gclient.args"', 'gclient_gn_args_file = "src/repo9/gclient.args"',
"gclient_gn_args = ['str_var']", "gclient_gn_args = ['str_var']",
'deps = {', 'deps = {',
' # src', ' # src',
@ -1383,7 +1386,8 @@ class GClientSmokeGIT(GClientSmokeBase):
self.assertFalse(os.path.exists(output_deps)) self.assertFalse(os.path.exists(output_deps))
self.gclient(['config', self.git_base + 'repo_14', '--name', 'src']) self.gclient(['config', self.git_base + 'repo_14', '--name', 'src'])
self.gclient(['sync']) # We can't sync since we haven't faked a CIPD server to get packages from.
self.gclient(['sync'], ignore_errors=True)
self.gclient(['flatten', '-v', '-v', '-v', '--output-deps', output_deps]) self.gclient(['flatten', '-v', '-v', '-v', '--output-deps', output_deps])
with open(output_deps) as f: with open(output_deps) as f:
@ -1452,7 +1456,7 @@ class GClientSmokeGITMutates(GClientSmokeBase):
# Commit new change to repo to make repo_2's hash use a custom_var. # Commit new change to repo to make repo_2's hash use a custom_var.
cur_deps = self.FAKE_REPOS.git_hashes['repo_1'][-1][1]['DEPS'] cur_deps = self.FAKE_REPOS.git_hashes['repo_1'][-1][1]['DEPS']
repo_2_hash = self.FAKE_REPOS.git_hashes['repo_2'][1][0][:7] repo_2_hash = self.FAKE_REPOS.git_hashes['repo_2'][1][0]
new_deps = cur_deps.replace('repo_2@%s\'' % repo_2_hash, new_deps = cur_deps.replace('repo_2@%s\'' % repo_2_hash,
'repo_2@\' + Var(\'r2hash\')') 'repo_2@\' + Var(\'r2hash\')')
new_deps = 'vars = {\'r2hash\': \'%s\'}\n%s' % (repo_2_hash, new_deps) new_deps = 'vars = {\'r2hash\': \'%s\'}\n%s' % (repo_2_hash, new_deps)
@ -1529,7 +1533,7 @@ class GClientSmokeGITMutates(GClientSmokeBase):
return return
# Create an extra commit in repo_2 and point DEPS to its hash. # Create an extra commit in repo_2 and point DEPS to its hash.
cur_deps = self.FAKE_REPOS.git_hashes['repo_1'][-1][1]['DEPS'] cur_deps = self.FAKE_REPOS.git_hashes['repo_1'][-1][1]['DEPS']
repo_2_hash_old = self.FAKE_REPOS.git_hashes['repo_2'][1][0][:7] repo_2_hash_old = self.FAKE_REPOS.git_hashes['repo_2'][1][0]
self.FAKE_REPOS._commit_git('repo_2', { # pylint: disable=protected-access self.FAKE_REPOS._commit_git('repo_2', { # pylint: disable=protected-access
'last_file': 'file created in last commit', 'last_file': 'file created in last commit',
}) })

Loading…
Cancel
Save