Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions codeflash/cli_cmds/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -478,5 +478,12 @@ def _build_parser() -> ArgumentParser:
action="store_true",
help="Subagent mode: skip all interactive prompts with sensible defaults. Designed for AI agent integrations.",
)
parser.add_argument(
"--since-commit",
type=str,
default=None,
help="Optimize functions changed since this commit hash (diff from this commit to HEAD). "
"Useful when multiple commits were made in a session.",
)

return parser
13 changes: 11 additions & 2 deletions codeflash/code_utils/git_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,11 @@


def get_git_diff(
repo_directory: Path | None = None, *, only_this_commit: Optional[str] = None, uncommitted_changes: bool = False
repo_directory: Path | None = None,
*,
only_this_commit: Optional[str] = None,
uncommitted_changes: bool = False,
since_commit: Optional[str] = None,
) -> dict[str, list[int]]:
from codeflash.languages.registry import get_supported_extensions

Expand All @@ -30,7 +34,12 @@ def get_git_diff(
# Use all registered extensions (Python + JS/TS + Java etc.) rather than
# current_language_support() which defaults to Python before language detection runs.
supported_extensions = set(get_supported_extensions())
if only_this_commit:
if since_commit:
# Diff from a base commit to HEAD — captures all changes across multiple commits
uni_diff_text = repository.git.diff(
since_commit, commit.hexsha, ignore_blank_lines=True, ignore_space_at_eol=True
)
elif only_this_commit:
uni_diff_text = repository.git.diff(
only_this_commit + "^1", only_this_commit, ignore_blank_lines=True, ignore_space_at_eol=True
)
Expand Down
16 changes: 12 additions & 4 deletions codeflash/discovery/functions_to_optimize.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,7 @@ def get_functions_to_optimize(
project_root: Path,
module_root: Path,
previous_checkpoint_functions: dict[str, dict[str, str]] | None = None,
since_commit: str | None = None,
) -> tuple[dict[Path, list[FunctionToOptimize]], int, Path | None]:
assert sum([bool(optimize_all), bool(replay_test), bool(file)]) <= 1, (
"Only one of optimize_all, replay_test, or file should be provided"
Expand Down Expand Up @@ -313,10 +314,13 @@ def get_functions_to_optimize(

functions[file] = [found_function]
else:
logger.info("Finding all functions modified in the current git diff ...")
if since_commit:
logger.info("Finding all functions modified since commit %s ...", since_commit[:8])
else:
logger.info("Finding all functions modified in the current git diff ...")
console.rule()
ph("cli-optimizing-git-diff")
functions = get_functions_within_git_diff(uncommitted_changes=False)
functions = get_functions_within_git_diff(uncommitted_changes=False, since_commit=since_commit)
filtered_modified_functions, functions_count = filter_functions(
functions, test_cfg.tests_root, ignore_paths, project_root, module_root, previous_checkpoint_functions
)
Expand All @@ -325,8 +329,12 @@ def get_functions_to_optimize(
return filtered_modified_functions, functions_count, trace_file_path


def get_functions_within_git_diff(uncommitted_changes: bool) -> dict[Path, list[FunctionToOptimize]]:
modified_lines: dict[str, list[int]] = get_git_diff(uncommitted_changes=uncommitted_changes)
def get_functions_within_git_diff(
uncommitted_changes: bool, since_commit: str | None = None
) -> dict[Path, list[FunctionToOptimize]]:
modified_lines: dict[str, list[int]] = get_git_diff(
uncommitted_changes=uncommitted_changes, since_commit=since_commit
)
return get_functions_within_lines(modified_lines)


Expand Down
1 change: 1 addition & 0 deletions codeflash/optimization/optimizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,7 @@ def get_optimizable_functions(self) -> tuple[dict[Path, list[FunctionToOptimize]
project_root=project_root,
module_root=module_root,
previous_checkpoint_functions=self.args.previous_checkpoint_functions,
since_commit=getattr(self.args, "since_commit", None),
)

# Remap discovered file paths from the original repo to the worktree so
Expand Down
Loading