Commit 63b8c2a7 authored by Paweł Hajdan, Jr's avatar Paweł Hajdan, Jr Committed by Commit Bot

gclient: fetch arbitrary refs

Bug: 624178
Change-Id: I7ffbf58441e8762630c3beec642108bcc671aae6
Reviewed-on: https://chromium-review.googlesource.com/647848Reviewed-by: 's avatarAaron Gable <agable@chromium.org>
Commit-Queue: Paweł Hajdan Jr. <phajdan.jr@chromium.org>
parent c369b238
......@@ -543,6 +543,8 @@ class GitWrapper(SCMWrapper):
self._UpdateBranchHeads(options, fetch=True)
revision = self._AutoFetchRef(options, revision)
# This is a big hammer, debatable if it should even be here...
if options.force or options.reset:
target = 'HEAD'
......@@ -919,6 +921,7 @@ class GitWrapper(SCMWrapper):
if 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)
if self._GetCurrentBranch() is None:
......@@ -1148,12 +1151,15 @@ class GitWrapper(SCMWrapper):
checkout_args.append(ref)
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,
refspec=None):
cfg = gclient_utils.DefaultIndexPackConfig(self.url)
fetch_cmd = cfg + [
'fetch',
remote or self.remote,
]
if refspec:
fetch_cmd.append(refspec)
if prune:
fetch_cmd.append('--prune')
......@@ -1185,6 +1191,17 @@ class GitWrapper(SCMWrapper):
if fetch and need_fetch:
self._Fetch(options, prune=options.force)
def _AutoFetchRef(self, options, revision):
"""Attempts to fetch |revision| if not available in local repo.
Returns possibly updated revision."""
try:
self._Capture(['rev-parse', revision])
except subprocess2.CalledProcessError:
self._Fetch(options, refspec=revision)
revision = self._Capture(['rev-parse', 'FETCH_HEAD'])
return revision
def _Run(self, args, options, show_header=True, **kwargs):
# Disable 'unused options' warning | pylint: disable=unused-argument
kwargs.setdefault('cwd', self.checkout_path)
......
......@@ -281,6 +281,12 @@ class FakeReposBase(object):
new_tree = tree.copy()
self.git_hashes[repo].append((commit_hash, new_tree))
def _fast_import_git(self, repo, data):
repo_root = join(self.git_root, repo)
logging.debug('%s: fast-import %s', repo, data)
subprocess2.check_call(
['git', 'fast-import', '--quiet'], cwd=repo_root, stdin=data)
def check_port_is_free(self, port):
sock = socket.socket()
try:
......@@ -298,7 +304,7 @@ class FakeReposBase(object):
class FakeRepos(FakeReposBase):
"""Implements populateGit()."""
NB_GIT_REPOS = 12
NB_GIT_REPOS = 13
def populateGit(self):
# Testing:
......@@ -620,6 +626,43 @@ deps = {
'origin': 'git/repo_12@1\n',
})
self._fast_import_git('repo_12', """blob
mark :1
data 6
Hello
blob
mark :2
data 4
Bye
reset refs/changes/1212
commit refs/changes/1212
mark :3
author Bob <bob@example.com> 1253744361 -0700
committer Bob <bob@example.com> 1253744361 -0700
data 8
A and B
M 100644 :1 a
M 100644 :2 b
""")
self._commit_git('repo_13', {
'DEPS': """
deps = {
'src/repo12': '/repo_12',
}""",
'origin': 'git/repo_13@1\n',
})
self._commit_git('repo_13', {
'DEPS': """
deps = {
'src/repo12': '/repo_12@refs/changes/1212',
}""",
'origin': 'git/repo_13@2\n',
})
class FakeRepoSkiaDEPS(FakeReposBase):
"""Simulates the Skia DEPS transition in Chrome."""
......
......@@ -792,8 +792,11 @@ class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9')
self.assertEquals(self.getCurrentBranch(), 'feature')
self.checkNotInStdout('Checked out feature to a detached HEAD')
# indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout(
'Checked out 9a51244740b25fa2ded5252ca00a3178d3f665a9 '
'to a detached HEAD')
rmtree(origin_root_dir)
......
......@@ -439,6 +439,36 @@ class GClientSmokeGIT(GClientSmokeBase):
])
self.assertTree(tree)
def testSyncFetch(self):
if not self.enabled:
return
self.gclient(['config', self.git_base + 'repo_13', '--name', 'src'])
_out, _err, rc = self.gclient(['sync', '-v', '-v', '-v'])
self.assertEquals(0, rc)
def testSyncFetchUpdate(self):
if not self.enabled:
return
self.gclient(['config', self.git_base + 'repo_13', '--name', 'src'])
# Sync to an earlier revision first, one that doesn't refer to
# non-standard refs.
_out, _err, rc = self.gclient(
['sync', '-v', '-v', '-v', '--revision', self.githash('repo_13', 1)])
self.assertEquals(0, rc)
# Make sure update that pulls a non-standard ref works.
_out, _err, rc = self.gclient(['sync', '-v', '-v', '-v'])
self.assertEquals(0, rc)
def testSyncDirect(self):
if not self.enabled:
return
self.gclient(['config', self.git_base + 'repo_12', '--name', 'src'])
_out, _err, rc = self.gclient(
['sync', '-v', '-v', '-v', '--revision', 'refs/changes/1212'])
self.assertEquals(0, rc)
def testRunHooks(self):
if not self.enabled:
return
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment