Skip to content

Commit

Permalink
Combine Git get_tag_revs and get_branch_revs into single get_refs met…
Browse files Browse the repository at this point in the history
…hod.
  • Loading branch information
carljm committed May 29, 2013
1 parent 92e0dbb commit fa81a41
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 72 deletions.
66 changes: 22 additions & 44 deletions pip/vcs/git.py
Expand Up @@ -67,8 +67,7 @@ def check_rev_options(self, rev, dest, rev_options):
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:
Expand Down Expand Up @@ -129,30 +128,24 @@ def get_revision(self, location):
[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):
rev_names = call_subprocess([self.cmd, 'show-ref'],
show_stdout=False, cwd=location)
branch_revs = {}
for line in rev_names.strip().splitlines():
rev, ref = line.split(' ', 1)
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()
branch = None
ref_name = None
if ref.startswith('refs/remotes/'):
branch = ref[len('refs/remotes/'):]
ref_name = ref[len('refs/remotes/'):]
elif ref.startswith('refs/heads/'):
branch = ref[len('refs/heads/'):]
if branch is not None:
branch_revs[branch] = rev.strip()
return branch_revs
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)
Expand All @@ -162,19 +155,14 @@ def get_src_requirement(self, dist, location, find_tags):
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

Expand All @@ -197,16 +185,6 @@ def get_url_rev(self):

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_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
Expand Down
2 changes: 1 addition & 1 deletion tests/test_freeze.py
Expand Up @@ -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)

Expand Down
48 changes: 21 additions & 27 deletions tests/test_vcs_git.py
Expand Up @@ -11,30 +11,32 @@
)


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)
env.run('git', 'tag', '0.2', cwd=version_pkg_path)
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
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)
Expand All @@ -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
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', '.', [])
Expand Down

1 comment on commit fa81a41

@cjerdonek
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like this change may have caused issue #1083.

Please sign in to comment.