Skip to content

Commit d389946

Browse files
CM-55207-Fix commit range parsing for empty remote
1 parent 348852c commit d389946

File tree

2 files changed

+77
-0
lines changed

2 files changed

+77
-0
lines changed

cycode/cli/files_collector/commit_range_documents.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -448,9 +448,26 @@ def parse_commit_range(commit_range: str, path: str) -> tuple[Optional[str], Opt
448448
- 'commit' (interpreted as 'commit..HEAD')
449449
- '..to' (interpreted as 'HEAD..to')
450450
- 'from..' (interpreted as 'from..HEAD')
451+
- '--all' (interpreted as 'first_commit..HEAD' to scan all commits)
451452
"""
452453
repo = git_proxy.get_repo(path)
453454

455+
# Handle '--all' special case: scan all commits from first to HEAD
456+
# Usually represents an empty remote repository
457+
if commit_range == '--all':
458+
try:
459+
head_commit = repo.rev_parse(consts.GIT_HEAD_COMMIT_REV).hexsha
460+
all_commits = repo.git.rev_list('--reverse', head_commit).strip()
461+
if all_commits:
462+
first_commit = all_commits.splitlines()[0]
463+
return first_commit, head_commit, '..'
464+
else:
465+
logger.warning("No commits found for range '%s'", commit_range)
466+
return None, None, None
467+
except Exception as e:
468+
logger.warning("Failed to parse commit range '%s'", commit_range, exc_info=e)
469+
return None, None, None
470+
454471
separator = '..'
455472
if '...' in commit_range:
456473
from_spec, to_spec = commit_range.split('...', 1)

tests/cli/files_collector/test_commit_range_documents.py

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -882,6 +882,66 @@ def test_single_commit_spec(self) -> None:
882882
parsed_from, parsed_to, separator = parse_commit_range(a, temp_dir)
883883
assert (parsed_from, parsed_to, separator) == (a, c, '..')
884884

885+
def test_parse_all_for_empty_remote_scenario(self) -> None:
886+
"""Test that '--all' is parsed correctly for empty remote repository.
887+
This repository has one commit locally.
888+
"""
889+
with temporary_git_repository() as (temp_dir, repo):
890+
# Create a local commit (simulating first commit to empty remote)
891+
test_file = os.path.join(temp_dir, 'test.py')
892+
with open(test_file, 'w') as f:
893+
f.write("print('test')")
894+
895+
repo.index.add(['test.py'])
896+
commit = repo.index.commit('Initial commit')
897+
898+
# Test that '--all' (returned by calculate_pre_push_commit_range for empty remote)
899+
# can be parsed to a valid commit range
900+
parsed_from, parsed_to, separator = parse_commit_range('--all', temp_dir)
901+
902+
# Should return first commit to HEAD (which is the only commit in this case)
903+
assert parsed_from == commit.hexsha
904+
assert parsed_to == commit.hexsha
905+
assert separator == '..'
906+
907+
def test_parse_all_for_empty_remote_scenario_with_two_commits(self) -> None:
908+
"""Test that '--all' is parsed correctly for empty remote repository.
909+
This repository has two commits locally.
910+
"""
911+
with temporary_git_repository() as (temp_dir, repo):
912+
# Create first commit
913+
test_file = os.path.join(temp_dir, 'test.py')
914+
with open(test_file, 'w') as f:
915+
f.write("print('test')")
916+
917+
repo.index.add(['test.py'])
918+
commit1 = repo.index.commit('First commit')
919+
920+
# Create second commit
921+
test_file2 = os.path.join(temp_dir, 'test2.py')
922+
with open(test_file2, 'w') as f:
923+
f.write("print('test2')")
924+
925+
repo.index.add(['test2.py'])
926+
commit2 = repo.index.commit('Second commit')
927+
928+
# Test that '--all' returns first commit to HEAD (second commit)
929+
parsed_from, parsed_to, separator = parse_commit_range('--all', temp_dir)
930+
931+
# Should return first commit to HEAD (second commit)
932+
assert parsed_from == commit1.hexsha # First commit
933+
assert parsed_to == commit2.hexsha # HEAD (second commit)
934+
assert separator == '..'
935+
936+
def test_parse_all_with_empty_repository_returns_none(self) -> None:
937+
"""Test that '--all' returns None when repository has no commits."""
938+
with temporary_git_repository() as (temp_dir, repo):
939+
# Empty repository with no commits
940+
parsed_from, parsed_to, separator = parse_commit_range('--all', temp_dir)
941+
# Should return None, None, None when HEAD doesn't exist
942+
assert parsed_from is None
943+
assert parsed_to is None
944+
assert separator is None
885945

886946
class TestParsePreReceiveInput:
887947
"""Test the parse_pre_receive_input function with various pre-receive hook input scenarios."""

0 commit comments

Comments
 (0)