Merge pull request #967 from carljm/bugfix-git183-v2

Use git show-ref instead of git branch for better future-proofness.
This commit is contained in:
Jannis Leidel 2013-05-30 00:01:22 -07:00
commit b2874f500b
3 changed files with 47 additions and 79 deletions

View File

@ -67,8 +67,7 @@ class Git(VersionControl):
and branches may need origin/ as a prefix.
Returns the SHA1 of the branch or tag if found.
"""
revisions = self.get_tag_revs(dest)
revisions.update(self.get_branch_revs(dest))
revisions = self.get_refs(dest)
origin_rev = 'origin/%s' % rev
if origin_rev in revisions:
@ -129,27 +128,24 @@ class Git(VersionControl):
[self.cmd, 'rev-parse', 'HEAD'], show_stdout=False, cwd=location)
return current_rev.strip()
def get_tag_revs(self, location):
tags = self._get_all_tag_names(location)
tag_revs = {}
for line in tags.splitlines():
tag = line.strip()
rev = self._get_revision_from_rev_parse(tag, location)
tag_revs[tag] = rev.strip()
return tag_revs
def get_branch_revs(self, location):
branches = self._get_all_branch_names(location)
branch_revs = {}
for line in branches.splitlines():
if '(no branch)' in line:
continue
line = line.split('->')[0].strip()
# actual branch case
branch = "".join(b for b in line.split() if b != '*')
rev = self._get_revision_from_rev_parse(branch, location)
branch_revs[branch] = rev.strip()
return branch_revs
def get_refs(self, location):
"""Return map of named refs (branches or tags) to commit hashes."""
output = call_subprocess([self.cmd, 'show-ref'],
show_stdout=False, cwd=location)
rv = {}
for line in output.strip().splitlines():
commit, ref = line.split(' ', 1)
ref = ref.strip()
ref_name = None
if ref.startswith('refs/remotes/'):
ref_name = ref[len('refs/remotes/'):]
elif ref.startswith('refs/heads/'):
ref_name = ref[len('refs/heads/'):]
elif ref.startswith('refs/tags/'):
ref_name = ref[len('refs/tags/'):]
if ref_name is not None:
rv[ref_name] = commit.strip()
return rv
def get_src_requirement(self, dist, location, find_tags):
repo = self.get_url(location)
@ -159,19 +155,14 @@ class Git(VersionControl):
if not repo:
return None
current_rev = self.get_revision(location)
tag_revs = self.get_tag_revs(location)
branch_revs = self.get_branch_revs(location)
refs = self.get_refs(location)
# refs maps names to commit hashes; we need the inverse
# if multiple names map to a single commit, this arbitrarily picks one
names_by_commit = dict((commit, ref) for ref, commit in refs.items())
if current_rev in tag_revs:
if current_rev in names_by_commit:
# It's a tag
full_egg_name = '%s-%s' % (egg_project_name, tag_revs[current_rev])
elif (current_rev in branch_revs and
branch_revs[current_rev] != 'origin/master'):
# It's the head of a branch
full_egg_name = '%s-%s' % (
egg_project_name,
branch_revs[current_rev].replace('origin/', '')
)
full_egg_name = '%s-%s' % (egg_project_name, names_by_commit[current_rev])
else:
full_egg_name = '%s-dev' % egg_project_name
@ -194,23 +185,6 @@ class Git(VersionControl):
return url, rev
def _get_all_tag_names(self, location):
return call_subprocess([self.cmd, 'tag', '-l'],
show_stdout=False,
raise_on_returncode=False,
cwd=location)
def _get_all_branch_names(self, location):
remote_branches = call_subprocess([self.cmd, 'branch', '-r'],
show_stdout=False, cwd=location)
local_branches = call_subprocess([self.cmd, 'branch', '-l'],
show_stdout=False, cwd=location)
return remote_branches + local_branches
def _get_revision_from_rev_parse(self, name, location):
return call_subprocess([self.cmd, 'rev-parse', name],
show_stdout=False, cwd=location)
def update_submodules(self, location):
if not os.path.exists(os.path.join(location, '.gitmodules')):
return

View File

@ -107,7 +107,7 @@ def test_freeze_git_clone():
Script result: pip freeze -f %(repo)s#egg=pip_test_package
-- stdout: --------------------
-f %(repo)s#egg=pip_test_package...
-e %(repo)s@...#egg=pip_test_package-dev
-e %(repo)s@...#egg=pip_test_package-0.1.1
...""" % {'repo': local_checkout('git+http://github.com/pypa/pip-test-package.git')})
_check_output(result, expected)

View File

@ -11,7 +11,7 @@ from tests.lib.git_submodule_helpers import (
)
def test_get_tag_revs_should_return_tag_name_and_commit_pair():
def test_get_refs_should_return_tag_name_and_commit_pair():
env = reset_env()
version_pkg_path = _create_test_package(env)
env.run('git', 'tag', '0.1', cwd=version_pkg_path)
@ -19,22 +19,24 @@ def test_get_tag_revs_should_return_tag_name_and_commit_pair():
commit = env.run('git', 'rev-parse', 'HEAD',
cwd=version_pkg_path).stdout.strip()
git = Git()
result = git.get_tag_revs(version_pkg_path)
assert result == {'0.1': commit, '0.2': commit}, result
result = git.get_refs(version_pkg_path)
assert result['0.1'] == commit, result
assert result['0.2'] == commit, result
def test_get_branch_revs_should_return_branch_name_and_commit_pair():
def test_get_refs_should_return_branch_name_and_commit_pair():
env = reset_env()
version_pkg_path = _create_test_package(env)
env.run('git', 'branch', 'branch0.1', cwd=version_pkg_path)
commit = env.run('git', 'rev-parse', 'HEAD',
cwd=version_pkg_path).stdout.strip()
git = Git()
result = git.get_branch_revs(version_pkg_path)
assert result == {'master': commit, 'branch0.1': commit}
result = git.get_refs(version_pkg_path)
assert result['master'] == commit, result
assert result['branch0.1'] == commit, result
def test_get_branch_revs_should_ignore_no_branch():
def test_get_refs_should_ignore_no_branch():
env = reset_env()
version_pkg_path = _create_test_package(env)
env.run('git', 'branch', 'branch0.1', cwd=version_pkg_path)
@ -44,40 +46,32 @@ def test_get_branch_revs_should_ignore_no_branch():
env.run('git', 'checkout', commit,
cwd=version_pkg_path, expect_stderr=True)
git = Git()
result = git.get_branch_revs(version_pkg_path)
assert result == {'master': commit, 'branch0.1': commit}
result = git.get_refs(version_pkg_path)
assert result['master'] == commit, result
assert result['branch0.1'] == commit, result
@patch('pip.vcs.git.Git.get_tag_revs')
@patch('pip.vcs.git.Git.get_branch_revs')
def test_check_rev_options_should_handle_branch_name(branches_revs_mock,
tags_revs_mock):
branches_revs_mock.return_value = {'master': '123456'}
tags_revs_mock.return_value = {'0.1': '123456'}
@patch('pip.vcs.git.Git.get_refs')
def test_check_rev_options_should_handle_branch_name(get_refs_mock):
get_refs_mock.return_value = {'master': '123456', '0.1': '123456'}
git = Git()
result = git.check_rev_options('master', '.', [])
assert result == ['123456']
@patch('pip.vcs.git.Git.get_tag_revs')
@patch('pip.vcs.git.Git.get_branch_revs')
def test_check_rev_options_should_handle_tag_name(branches_revs_mock,
tags_revs_mock):
branches_revs_mock.return_value = {'master': '123456'}
tags_revs_mock.return_value = {'0.1': '123456'}
@patch('pip.vcs.git.Git.get_refs')
def test_check_rev_options_should_handle_tag_name(get_refs_mock):
get_refs_mock.return_value = {'master': '123456', '0.1': '123456'}
git = Git()
result = git.check_rev_options('0.1', '.', [])
assert result == ['123456']
@patch('pip.vcs.git.Git.get_tag_revs')
@patch('pip.vcs.git.Git.get_branch_revs')
def test_check_rev_options_should_handle_ambiguous_commit(branches_revs_mock,
tags_revs_mock):
branches_revs_mock.return_value = {'master': '123456'}
tags_revs_mock.return_value = {'0.1': '123456'}
@patch('pip.vcs.git.Git.get_refs')
def test_check_rev_options_should_handle_ambiguous_commit(get_refs_mock):
get_refs_mock.return_value = {'master': '123456', '0.1': '123456'}
git = Git()
result = git.check_rev_options('0.1', '.', [])