diff --git a/codecov_cli/helpers/versioning_systems.py b/codecov_cli/helpers/versioning_systems.py index ae4bdc72..df0124e8 100644 --- a/codecov_cli/helpers/versioning_systems.py +++ b/codecov_cli/helpers/versioning_systems.py @@ -42,6 +42,20 @@ def is_available(cls): def get_fallback_value(self, fallback_field: FallbackFieldEnum): if fallback_field == FallbackFieldEnum.commit_sha: + # here we will get the commit SHA of the latest commit + # that is NOT a merge commit + p = subprocess.run( + # List current commit parent's SHA + ["git", "rev-parse", "HEAD^@"], + capture_output=True, + ) + parents_hash = p.stdout.decode().strip().splitlines() + if len(parents_hash) == 2: + # IFF the current commit is a merge commit it will have 2 parents + # We return the 2nd one - The commit that came from the branch merged into ours + return parents_hash[1] + # At this point we know the current commit is not a merge commit + # so we get it's SHA and return that p = subprocess.run(["git", "log", "-1", "--format=%H"], capture_output=True) if p.stdout: return p.stdout.decode().strip() @@ -56,7 +70,7 @@ def get_fallback_value(self, fallback_field: FallbackFieldEnum): return branch_name if branch_name != "HEAD" else None if fallback_field == FallbackFieldEnum.slug: - # if there are multiple remotes, we will prioritize using the one called 'origin' if it exsits, else we will use the first one in 'git remote' list + # if there are multiple remotes, we will prioritize using the one called 'origin' if it exists, else we will use the first one in 'git remote' list p = subprocess.run(["git", "remote"], capture_output=True) @@ -78,7 +92,7 @@ def get_fallback_value(self, fallback_field: FallbackFieldEnum): return parse_slug(remote_url) if fallback_field == FallbackFieldEnum.git_service: - # if there are multiple remotes, we will prioritize using the one called 'origin' if it exsits, else we will use the first one in 'git remote' list + # if there are multiple remotes, we will prioritize using the one called 'origin' if it exists, else we will use the first one in 'git remote' list p = subprocess.run(["git", "remote"], capture_output=True) if not p.stdout: diff --git a/tests/helpers/test_versioning_systems.py b/tests/helpers/test_versioning_systems.py index c0532ef6..cc74410f 100644 --- a/tests/helpers/test_versioning_systems.py +++ b/tests/helpers/test_versioning_systems.py @@ -8,17 +8,28 @@ class TestGitVersioningSystem(object): @pytest.mark.parametrize( - "commit_sha,expected", [("", None), (b" random_sha ", "random_sha")] + "runs_output,expected", + [ + # No output for parents nor commit + ([b"", b""], None), + # No output for parents, commit has SHA + ([b"", b" random_sha"], "random_sha"), + # Commit is NOT a merge-commit + ([b" parent_sha", b" random_sha "], "random_sha"), + # Commit IS a merge-commit + ([b" parent_sha0\nparent_sha1", b" random_sha"], "parent_sha1"), + ], ) - def test_commit_sha(self, mocker, commit_sha, expected): - mocked_subprocess = MagicMock() + def test_commit_sha(self, mocker, runs_output, expected): + mocked_subprocess = [ + MagicMock(**{"stdout": runs_output[0]}), + MagicMock(**{"stdout": runs_output[1]}), + ] mocker.patch( "codecov_cli.helpers.versioning_systems.subprocess.run", - return_value=mocked_subprocess, + side_effect=mocked_subprocess, ) - mocked_subprocess.stdout = commit_sha - assert ( GitVersioningSystem().get_fallback_value(FallbackFieldEnum.commit_sha) == expected diff --git a/tests/services/upload/test_coverage_file_finder.py b/tests/services/upload/test_coverage_file_finder.py index 127fb31c..09c09c80 100644 --- a/tests/services/upload/test_coverage_file_finder.py +++ b/tests/services/upload/test_coverage_file_finder.py @@ -295,7 +295,9 @@ def test_find_coverage_files_with_user_specified_files_not_found(self): expected_paths = sorted([file.get_filename() for file in expected]) self.assertEqual(result, expected_paths) - def test_find_coverage_files_with_user_specified_files_in_default_ignored_folder(self): + def test_find_coverage_files_with_user_specified_files_in_default_ignored_folder( + self, + ): # Create some sample coverage files coverage_files = [ self.project_root / "coverage.xml",