From ca2e46b1ac3b9fd98d10eb3a7394815d7100b886 Mon Sep 17 00:00:00 2001 From: Lubomír Sedlář Date: Feb 01 2018 20:18:28 +0000 Subject: Fix getting current branch Running `git branch --contains` returns all branches that contain current commit. There can be multiple branches like that, which results in garbage value being returned. New implementation will return the branch that git thinks is checked out currently. It will report detached HEAD state properly. --- diff --git a/pag/utils.py b/pag/utils.py index 6caa2cd..e6d75e2 100644 --- a/pag/utils.py +++ b/pag/utils.py @@ -82,8 +82,11 @@ def get_default_upstream_branch(name): def get_current_local_branch(): - code, stdout = run(['git', 'branch', '--contains']) - return stdout.split(maxsplit=1)[1].strip() + _, stdout = run(['git', 'rev-parse', '--abbrev-ref', 'HEAD']) + branch = stdout.strip() + if branch == 'HEAD': + raise RuntimeError('Repo in detached HEAD state.') + return branch def repo_url(name, ssh=False, git=False, domain='pagure.io'): diff --git a/tests/test_utils.py b/tests/test_utils.py new file mode 100644 index 0000000..df6199e --- /dev/null +++ b/tests/test_utils.py @@ -0,0 +1,57 @@ +import os +import shlex +import shutil +import subprocess +import tempfile +import unittest + +from pag import utils + + +class TestGetCurrentBranch(unittest.TestCase): + + def cmd(self, cmd, *args, **kwargs): + print('$ %s' % ' '.join(shlex.quote(x) for x in cmd)) + cp = subprocess.run(cmd, *args, + cwd=self.repo, + stdout=subprocess.PIPE, + stderr=subprocess.STDOUT, + universal_newlines=True, + **kwargs) + print(cp.stdout) + + def setUp(self): + # Create git repository with some basic content + self.repo = tempfile.mkdtemp(prefix='test_current_branch_') + self.cmd(['git', 'init']) + with open(os.path.join(self.repo, 'file'), 'w') as f: + f.write('') + self.cmd(['git', 'add', '.']) + self.cmd(['git', 'commit', '-m', 'Initial commit']) + # and chdir into it. + os.chdir(self.repo) + + def tearDown(self): + shutil.rmtree(self.repo) + + def test_single_branch(self): + self.cmd(['git', 'checkout', '-b', 'test']) + self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) + + self.assertEqual(utils.get_current_local_branch(), 'test') + + def test_multiple_branches(self): + # There are two branches pointing at the current commit. + self.cmd(['git', 'checkout', '-b', 'test']) + self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) + self.cmd(['git', 'checkout', '-b', 'another']) + + self.assertEqual(utils.get_current_local_branch(), 'another') + + def test_detached_head(self): + self.cmd(['git', 'checkout', '-b', 'test']) + self.cmd(['git', 'commit', '--allow-empty', '-m', 'Dummy commit']) + self.cmd(['git', 'checkout', 'HEAD^']) + + with self.assertRaises(RuntimeError): + utils.get_current_local_branch()