diff --git a/git_cl.py b/git_cl.py index 29c03267c..bc6046bb3 100755 --- a/git_cl.py +++ b/git_cl.py @@ -4908,6 +4908,10 @@ def _UploadAllPrecheck(options, orig_args): since their last upload and a boolean of whether the user wants to cherry-pick and upload the current branch instead of uploading all cls. """ + cl = Changelist() + if cl.GetBranch() is None: + DieWithError('Can\'t upload from detached HEAD state. Get on a branch!') + branch_ref = None cls = [] must_upload_upstream = False diff --git a/tests/git_cl_test.py b/tests/git_cl_test.py index 75b6810bb..91e23902c 100755 --- a/tests/git_cl_test.py +++ b/tests/git_cl_test.py @@ -1692,7 +1692,9 @@ class TestGitCl(unittest.TestCase): 'current', 'upstream3', 'blank3', 'blank2', 'upstream2', 'blank1', 'upstream1', 'origin/main' ] - mockGetBranchRef.side_effect = ['refs/heads/%s' % b for b in branches] + mockGetBranchRef.side_effect = ( + ['refs/heads/current'] + # detached HEAD check + ['refs/heads/%s' % b for b in branches]) mockGetCommonAncestorWithUpstream.side_effect = [ 'commit3.5', 'commit3.5', @@ -1808,7 +1810,9 @@ class TestGitCl(unittest.TestCase): mockGetRemoteBranch.return_value = ('origin', 'refs/remotes/origin/main') branches = ['current', 'upstream3', 'main'] - mockGetBranchRef.side_effect = ['refs/heads/%s' % b for b in branches] + mockGetBranchRef.side_effect = ( + ['refs/heads/current'] + # detached HEAD check + ['refs/heads/%s' % b for b in branches]) mockGetCommonAncestorWithUpstream.side_effect = ['commit3.5', 'commit0.5'] mockFetchUpstreamTuple.side_effect = [('.', 'refs/heads/upstream3'), @@ -1864,7 +1868,12 @@ class TestGitCl(unittest.TestCase): orig_args = ['--preserve-tryjobs', '--chicken'] mockGetRemoteBranch.return_value = ('origin', 'refs/remotes/origin/main') - mockGetBranchRef.side_effect = ['refs/heads/current', 'refs/heads/main'] + mockGetBranchRef.side_effect = [ + 'refs/heads/current', # detached HEAD check + 'refs/heads/current', # call within while loop + 'refs/heads/main', + 'refs/heads/main' + ] mockGetCommonAncestorWithUpstream.return_value = 'commit3.5' mockFetchUpstreamTuple.return_value = ('', 'refs/heads/main') mockIsAncestor.return_value = True @@ -1889,6 +1898,12 @@ class TestGitCl(unittest.TestCase): with self.assertRaises(SystemExitMock): git_cl._UploadAllPrecheck(options, orig_args) + @mock.patch('scm.GIT.GetBranchRef', return_value=None) + def test_upload_all_precheck_detached_HEAD(self, mockGetBranchRef): + + with self.assertRaises(SystemExitMock): + git_cl._UploadAllPrecheck(optparse.Values(), []) + @mock.patch('git_cl.RunGit') @mock.patch('git_cl.CMDupload') @mock.patch('sys.stdin', StringIO('\n'))