Skip to content

Commit 1175a98

Browse files
mashraf-222claude
andcommitted
fix: handle git_remote=None and NoSuchPathError in multi-config path
In the multi-language orchestration path, handle_optimize_all_arg_parsing runs before config is loaded, so args.git_remote is unset. This caused repo.remote(name=None) to raise ValueError, crashing every --file/--all run without --no-pr. Default to "origin" when git_remote is not set. Also catch git.NoSuchPathError in check_running_in_git_repo and handle_optimize_all_arg_parsing so non-existent module_root paths return graceful errors instead of uncaught exceptions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1 parent 0c08b28 commit 1175a98

3 files changed

Lines changed: 51 additions & 3 deletions

File tree

codeflash/cli_cmds/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -253,14 +253,14 @@ def handle_optimize_all_arg_parsing(args: Namespace) -> Namespace:
253253
# Ensure that the user can actually open PRs on the repo.
254254
try:
255255
git_repo = git.Repo(search_parent_directories=True)
256-
except git.exc.InvalidGitRepositoryError:
256+
except (git.exc.InvalidGitRepositoryError, git.exc.NoSuchPathError):
257257
mode = "--all" if hasattr(args, "all") else "--file"
258258
logger.exception(
259259
f"I couldn't find a git repository in the current directory. "
260260
f"I need a git repository to run {mode} and open PRs for optimizations. Exiting..."
261261
)
262262
apologize_and_exit()
263-
git_remote = getattr(args, "git_remote", None)
263+
git_remote = getattr(args, "git_remote", None) or "origin"
264264
if not check_and_push_branch(git_repo, git_remote=git_remote):
265265
exit_with_message("Branch is not pushed...", error_on_exit=True)
266266
owner, repo = get_repo_owner_and_name(git_repo)

codeflash/code_utils/git_utils.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ def mirror_path(path: Path, src_root: Path, dest_root: Path) -> Path:
149149
def check_running_in_git_repo(module_root: str) -> bool:
150150
try:
151151
_ = git.Repo(module_root, search_parent_directories=True).git_dir
152-
except git.InvalidGitRepositoryError:
152+
except (git.InvalidGitRepositoryError, git.NoSuchPathError):
153153
return False
154154
else:
155155
return True

tests/test_multi_language_orchestration.py

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from pathlib import Path
66
from unittest.mock import MagicMock, patch
77

8+
import pytest
89
import tomlkit
910

1011
from codeflash.code_utils.config_parser import LanguageConfig, normalize_toml_config
@@ -769,3 +770,50 @@ def test_per_language_logging_shows_config_path(
769770
logged_messages = [str(call) for call in mock_log_info.call_args_list]
770771
processing_logs = [m for m in logged_messages if "Processing" in m and "config:" in m]
771772
assert len(processing_logs) >= 1
773+
774+
775+
class TestGitRepoDetectionEdgeCases:
776+
def test_check_running_in_git_repo_nonexistent_path(self) -> None:
777+
from codeflash.code_utils.git_utils import check_running_in_git_repo
778+
779+
assert check_running_in_git_repo("/nonexistent/path/that/does/not/exist") is False
780+
781+
def test_check_running_in_git_repo_none_uses_cwd(self) -> None:
782+
from codeflash.code_utils.git_utils import check_running_in_git_repo
783+
784+
# None defaults to CWD, which is inside the codeflash git repo
785+
assert check_running_in_git_repo(None) is True
786+
787+
def test_handle_optimize_all_git_remote_defaults_to_origin(self) -> None:
788+
import git as git_module
789+
790+
from codeflash.cli_cmds.cli import handle_optimize_all_arg_parsing
791+
792+
args = make_base_args(file="/some/file.java", no_pr=False)
793+
# Remove git_remote to simulate multi-config path where config hasn't loaded
794+
if hasattr(args, "git_remote"):
795+
delattr(args, "git_remote")
796+
797+
mock_repo = MagicMock(spec=git_module.Repo)
798+
with (
799+
patch("git.Repo", return_value=mock_repo),
800+
patch(
801+
"codeflash.code_utils.git_utils.check_and_push_branch", return_value=True
802+
) as mock_push,
803+
patch("codeflash.code_utils.git_utils.get_repo_owner_and_name", return_value=("owner", "repo")),
804+
patch("codeflash.code_utils.github_utils.require_github_app_or_exit"),
805+
):
806+
handle_optimize_all_arg_parsing(args)
807+
mock_push.assert_called_once()
808+
assert mock_push.call_args[1].get("git_remote") == "origin"
809+
810+
def test_handle_optimize_all_no_such_path_error(self) -> None:
811+
import git as git_module
812+
813+
from codeflash.cli_cmds.cli import handle_optimize_all_arg_parsing
814+
815+
args = make_base_args(file="/some/file.java", no_pr=False)
816+
817+
with patch("git.Repo", side_effect=git_module.exc.NoSuchPathError("/bad/path")):
818+
with pytest.raises(SystemExit):
819+
handle_optimize_all_arg_parsing(args)

0 commit comments

Comments
 (0)