Skip to content

Commit

Permalink
Determine branch in a smarter way
Browse files Browse the repository at this point in the history
The git module is determine if a version is a branch by regrex
check if it's a sha, that makes it confuse on tag vs branch.
This commit determines branch by check return code of
`git show-ref --verify --quiet refs/heads/<version>`, this will
always work because gilt always fetch and checkout, there must
have heads ref to a branch.
  • Loading branch information
tiewei committed Mar 28, 2017
1 parent 2f7edc9 commit 57a03c8
Show file tree
Hide file tree
Showing 2 changed files with 35 additions and 16 deletions.
20 changes: 18 additions & 2 deletions gilt/git.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import glob
import os
import re
import shutil

import sh
Expand Down Expand Up @@ -123,6 +122,23 @@ def _get_branch(version, debug=False):
util.run_command(cmd, debug=debug)
cmd = sh.git.bake('clean', '-d', '-x', '-f')
util.run_command(cmd, debug=debug)
if not re.match(r'\b[0-9a-f]{7,40}\b', str(version)):
if _is_branch(version, debug):
cmd = sh.git.bake('pull', rebase=True, ff_only=True)
util.run_command(cmd, debug=debug)


def _is_branch(version, debug=False):
"""
Determine a version is a git branch name or not.
:param version: A string containing the branch/tag/sha to be exported.
:param debug: An optional bool to toggle debug output.
:return: bool
"""
cmd = sh.git.bake('show-ref', '--verify', '--quiet',
"refs/heads/{}".format(version))
try:
util.run_command(cmd, debug=debug)
return True
except sh.ErrorReturnCode:
return False
31 changes: 17 additions & 14 deletions test/test_git.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,9 @@ def test_get_branch(mocker, patched_run_command):
mocker.call(sh.git.bake('fetch'), debug=False),
mocker.call(sh.git.bake('checkout', 'branch'), debug=False),
mocker.call(sh.git.bake('clean', '-d', '-x', '-f'), debug=False),
mocker.call(sh.git.bake(
'show-ref', '--verify', '--quiet', 'refs/heads/branch'),
debug=False),
mocker.call(sh.git.bake('pull', rebase=True, ff_only=True),
debug=False)
]
Expand All @@ -142,27 +145,27 @@ def test_get_branch(mocker, patched_run_command):
assert expected == patched_run_command.mock_calls


def test_get_branch_does_not_pull_on_sha(mocker, patched_run_command):
git._get_branch('e14ebe0')
def test_get_nonbranch(mocker, patched_run_command):
mocker.patch("gilt.git._is_branch").return_value = False
git._get_branch('nonbranch')
# yapf: disable
expected = [
mocker.call(sh.git.bake('fetch'), debug=False),
mocker.call(sh.git.bake('checkout', 'e14ebe0'), debug=False),
mocker.call(sh.git.bake('checkout', 'nonbranch'), debug=False),
mocker.call(sh.git.bake('clean', '-d', '-x', '-f'), debug=False)
]
# yapf: enable

assert expected == patched_run_command.mock_calls


def test_get_branch_handles_int_sha(mocker, patched_run_command):
git._get_branch(1234567)
# yapf: disable
expected = [
mocker.call(sh.git.bake('fetch'), debug=False),
mocker.call(sh.git.bake('checkout', '1234567'), debug=False),
mocker.call(sh.git.bake('clean', '-d', '-x', '-f'), debug=False)
]
# yapf: enable

assert expected == patched_run_command.mock_calls
@slow
def test_is_branch(temp_dir):
name = 'retr0h.ansible-etcd'
repo = 'https://github.com/retr0h/ansible-etcd.git'
destination = os.path.join(temp_dir.strpath, name)
git.clone(name, repo, destination)
os.chdir(destination)
assert git._is_branch("master")
assert not git._is_branch("1.1")
assert not git._is_branch("888ef7b")

0 comments on commit 57a03c8

Please sign in to comment.