Handle branch or commit refs in the url for unmanaged git solutions

This allows having a git repo cloned on a specific branch or commit, similar to
what's possible for svn solutions by specifying a url like svnrepo/branches/foo

Having the possibility to check the code out on a specific branch makes the
initial code checkout workflow simpler, and allows specifying all the relevant
info directly in the fetch recipe, instead of  having to deal with branches
manually afterwards (which is the whole purpose of recipes in the first place)

So with this change, I'm able to do the following in my custom fetch recipe:

    solution = {
        'name' : 'src',
        'url' : 'git@github.snei.sony.com:SNEI/chromium.git@refs/heads/custombranch',
        <following lines skipped>

Review URL: https://codereview.chromium.org/289863012

git-svn-id: svn://svn.chromium.org/chrome/trunk/tools/depot_tools@273675 0039d316-1c4b-4281-b951-d872f2087c98
parent d057f9af
......@@ -331,7 +331,9 @@ class GitWrapper(SCMWrapper):
# Override the revision number.
revision = str(options.revision)
if revision == 'unmanaged':
revision = None
# Check again for a revision in case an initial ref was specified
# in the url, for example bla.git@refs/heads/custombranch
revision = deps_revision
managed = False
if not revision:
revision = default_rev
......@@ -819,12 +821,10 @@ class GitWrapper(SCMWrapper):
if os.listdir(tmp_dir):
self.Print('_____ removing non-empty tmp dir %s' % tmp_dir)
gclient_utils.rmtree(tmp_dir)
if revision.startswith('refs/heads/'):
self._Run(
['checkout', '--quiet', revision.replace('refs/heads/', '')], options)
else:
self._Run(['checkout', '--quiet', revision.replace('refs/heads/', '')],
options)
if self._GetCurrentBranch() is None:
# Squelch git's very verbose detached HEAD warning and use our own
self._Run(['checkout', '--quiet', revision], options)
self.Print(
('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'
......
......@@ -891,7 +891,9 @@ from :3
TestCaseUtils.setUp(self)
unittest.TestCase.setUp(self)
self.url = 'git://foo'
self.root_dir = tempfile.mkdtemp()
# The .git suffix allows gclient_scm to recognize the dir as a git repo
# when cloning it locally
self.root_dir = tempfile.mkdtemp('.git')
self.relpath = '.'
self.base_path = join(self.root_dir, self.relpath)
self.enabled = self.CreateGitRepo(self.sample_git_import, self.base_path)
......@@ -1377,6 +1379,181 @@ class ManagedGitWrapperTestCaseMox(BaseTestCase):
class UnmanagedGitWrapperTestCase(BaseGitWrapperTestCase):
def checkInStdout(self, expected):
value = sys.stdout.getvalue()
sys.stdout.close()
# pylint: disable=E1101
self.assertIn(expected, value)
def checkNotInStdout(self, expected):
value = sys.stdout.getvalue()
sys.stdout.close()
# pylint: disable=E1101
self.assertNotIn(expected, value)
def getCurrentBranch(self):
# Returns name of current branch or HEAD for detached HEAD
branch = gclient_scm.scm.GIT.Capture(['rev-parse', '--abbrev-ref', 'HEAD'],
cwd=self.base_path)
if branch == 'HEAD':
return None
return branch
def testUpdateClone(self):
if not self.enabled:
return
options = self.Options()
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.CreateSCM(url=origin_root_dir,
root_dir=self.root_dir,
relpath=self.relpath)
expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b")]
file_list = []
options.revision = 'unmanaged'
scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None),
'069c602044c5388d2d15c3f875b057c852003458')
# indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout(
'Checked out refs/remotes/origin/master to a detached HEAD')
rmtree(origin_root_dir)
def testUpdateCloneOnCommit(self):
if not self.enabled:
return
options = self.Options()
origin_root_dir = self.root_dir
self.root_dir = tempfile.mkdtemp()
self.relpath = '.'
self.base_path = join(self.root_dir, self.relpath)
url_with_commit_ref = origin_root_dir +\
'@a7142dc9f0009350b96a11f372b6ea658592aa95'
scm = gclient_scm.CreateSCM(url=url_with_commit_ref,
root_dir=self.root_dir,
relpath=self.relpath)
expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b")]
file_list = []
options.revision = 'unmanaged'
scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None),
'a7142dc9f0009350b96a11f372b6ea658592aa95')
# indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout(
'Checked out a7142dc9f0009350b96a11f372b6ea658592aa95 to a detached HEAD')
rmtree(origin_root_dir)
def testUpdateCloneOnBranch(self):
if not self.enabled:
return
options = self.Options()
origin_root_dir = self.root_dir
self.root_dir = tempfile.mkdtemp()
self.relpath = '.'
self.base_path = join(self.root_dir, self.relpath)
url_with_branch_ref = origin_root_dir + '@feature'
scm = gclient_scm.CreateSCM(url=url_with_branch_ref,
root_dir=self.root_dir,
relpath=self.relpath)
expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b"),
join(self.base_path, "c")]
file_list = []
options.revision = 'unmanaged'
scm.update(options, (), file_list)
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')
rmtree(origin_root_dir)
def testUpdateCloneOnDetachedBranch(self):
if not self.enabled:
return
options = self.Options()
origin_root_dir = self.root_dir
self.root_dir = tempfile.mkdtemp()
self.relpath = '.'
self.base_path = join(self.root_dir, self.relpath)
url_with_branch_ref = origin_root_dir + '@refs/remotes/origin/feature'
scm = gclient_scm.CreateSCM(url=url_with_branch_ref,
root_dir=self.root_dir,
relpath=self.relpath)
expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b"),
join(self.base_path, "c")]
file_list = []
options.revision = 'unmanaged'
scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9')
# indicates detached HEAD
self.assertEquals(self.getCurrentBranch(), None)
self.checkInStdout(
'Checked out refs/remotes/origin/feature to a detached HEAD')
rmtree(origin_root_dir)
def testUpdateCloneOnBranchHead(self):
if not self.enabled:
return
options = self.Options()
origin_root_dir = self.root_dir
self.root_dir = tempfile.mkdtemp()
self.relpath = '.'
self.base_path = join(self.root_dir, self.relpath)
url_with_branch_ref = origin_root_dir + '@refs/heads/feature'
scm = gclient_scm.CreateSCM(url=url_with_branch_ref,
root_dir=self.root_dir,
relpath=self.relpath)
expected_file_list = [join(self.base_path, "a"),
join(self.base_path, "b"),
join(self.base_path, "c")]
file_list = []
options.revision = 'unmanaged'
scm.update(options, (), file_list)
self.assertEquals(file_list, expected_file_list)
self.assertEquals(scm.revinfo(options, (), None),
'9a51244740b25fa2ded5252ca00a3178d3f665a9')
self.assertEquals(self.getCurrentBranch(), 'feature')
self.checkNotInStdout(
'Checked out refs/heads/feature to a detached HEAD')
rmtree(origin_root_dir)
def testUpdateUpdate(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