Skip to content

fix: git diff auto-detection filters by current language instead of hardcoding .py#1855

Merged
aseembits93 merged 2 commits intomainfrom
fix/git-diff-multi-language-extension-filter
Mar 18, 2026
Merged

fix: git diff auto-detection filters by current language instead of hardcoding .py#1855
aseembits93 merged 2 commits intomainfrom
fix/git-diff-multi-language-extension-filter

Conversation

@mashraf-222
Copy link
Contributor

Summary

  • get_git_diff() in code_utils/git_utils.py hardcoded .py as the only valid file extension when parsing git diffs
  • This caused the auto-detect flow (running codeflash without --file) to return 0 functions for Java, JavaScript, and TypeScript projects
  • This broke the Claude Code plugin integration where the stop hook runs codeflash --subagent without specifying --file, relying on git diff auto-detection to find changed functions

Problems fixed

Symptom: When running codeflash --subagent (or any invocation without --file) on a Java/JS/TS project, the pipeline discovers no functions to optimize and exits silently — even when the git diff contains changed functions.

Root cause: Line 42 of codeflash/code_utils/git_utils.py had if file_path.suffix != ".py": continue, which filtered out all non-Python files from the git diff results. This function is called by both get_functions_within_git_diff() and get_functions_within_commit() in discovery/functions_to_optimize.py.

Solution

Replaced the hardcoded .py check with current_language_support().file_extensions, which returns the correct extensions for whatever language is active in the session (e.g., (".java",) for Java, (".js", ".jsx", ".mjs") for JavaScript). The current language is already set by the time get_git_diff() is called during an optimization run.

Code changes

  • codeflash/code_utils/git_utils.py: Import current_language_support, resolve extensions once at function entry, use not in supported_extensions instead of != ".py"
  • tests/test_git_utils.py: Added 3 new tests:
    • test_java_diff_found_when_language_is_java — Java files discovered when language is Java
    • test_java_diff_ignored_when_language_is_python — Java files filtered out when language is Python
    • test_mixed_lang_diff_filters_by_current_language — mixed Python+Java diff correctly filters by active language

Testing

$ uv run pytest tests/test_git_utils.py -v
# 15 passed (12 existing + 3 new) — no regressions

🤖 Generated with Claude Code

…ardcoding .py

get_git_diff() hardcoded `.py` as the only valid file extension, causing
the auto-detect flow (no --file flag) to return 0 functions for Java,
JavaScript, and TypeScript projects. This broke the Claude Code plugin
integration where the hook runs `codeflash --subagent` without --file.

Now uses current_language_support().file_extensions to filter by the
active language's extensions dynamically.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@claude
Copy link
Contributor

claude bot commented Mar 17, 2026

Claude finished @mashraf-222's task in 2m 31s —— View job


PR Review Summary

  • Triage PR
  • Lint and type check
  • Resolve stale review threads (none found)
  • Code review
  • Duplicate detection
  • Test coverage

Prek Checks

✅ All checks pass (ruff lint, ruff format). Mypy CI also passing.


Code Review

The fix is correct and minimal. The change replaces the hardcoded != ".py" check at git_utils.py:45 with a dynamic lookup via current_language_support().file_extensions, which is the right approach given the existing language singleton pattern.

Observations:

  1. Import placement (git_utils.py:24) — The current_language_support import is done inside the function body to avoid circular imports. This is consistent with the existing codebase pattern and is correct.

  2. Default behavior preserved_current_language defaults to Language.PYTHON in current.py:37, so if set_current_language() was never called (e.g., Python-only tooling paths), behavior is unchanged.

  3. Extension lookup is efficientsupported_extensions is resolved once at function entry rather than per-iteration, which is good.

  4. One minor nit: The MIXED_LANG_DIFF test fixture at tests/test_git_utils.py:267 is a concatenation of two separate ---/+++ diff blocks without a diff --git header separating them. unidiff accepts this, but it's a non-standard format. Functionally fine since the tests pass and the fixture is test-only.

  5. Missing JS/TS test coverage — The new tests only exercise Java and Python. There's no test for JavaScript/TypeScript extensions (.js, .ts, .jsx). This isn't a blocker since the fix is generic, but a JS test would round out coverage.

No bugs, no security issues, no breaking API changes.


Duplicate Detection

No duplicates detected. The change is isolated to the get_git_diff() function and correctly delegates to the language registry rather than reimplementing extension logic elsewhere.


Test Coverage

All 15 tests pass (12 existing + 3 new). Coverage on codeflash/code_utils/git_utils.py is 64% — unchanged from before this PR since coverage of other git operations (push, branch detection, etc.) requires a live git repo. The get_git_diff function itself is well-covered by the test suite.


Overall: Clean, minimal fix with correct approach. ✅

@mashraf-222 mashraf-222 requested a review from aseembits93 March 17, 2026 18:43
aseembits93
aseembits93 previously approved these changes Mar 17, 2026
@aseembits93
Copy link
Contributor

@claude fix the failing windows unit test

@claude
Copy link
Contributor

claude bot commented Mar 17, 2026

Claude finished @aseembits93's task in 6m 24s —— View job


Fixed Failing Windows Unit Test

  • Gather context
  • Find failing Windows test in CI — tests/test_trace_benchmarks.py::test_trace_benchmark_decorator
  • Diagnose the issue
  • Fix the code
  • Commit and push

Root cause: codeflash/benchmarking/plugin/plugin.py:270 used time.time_ns() to measure benchmark elapsed time. On Windows, time.time_ns() wraps the system wall clock which has only ~15ms resolution. The sorter(list(reversed(range(500)))) benchmark completes in <1ms, so end - start = 0 ns. This caused validate_and_format_benchmark_table to classify the result as func_time > total_time (any non-zero function trace time exceeds a total of 0), storing (key, 0.0, 0.0, 0.0) and failing the assert total_time > 0.0 check.

Fix: Replaced time.time_ns() with time.perf_counter_ns() — the high-resolution performance counter (QueryPerformanceCounter on Windows, ~100ns precision). This is the correct timer for benchmarking since it's monotonic and has consistent sub-millisecond resolution on all platforms.

# Before
start = time.time_ns()
result = func(*args, **kwargs)
end = time.time_ns()

# After
start = time.perf_counter_ns()
result = func(*args, **kwargs)
end = time.perf_counter_ns()

All 3 trace benchmark tests pass locally. Pushed as commit 16f588c1.
| Branch

…ision

time.time_ns() has ~15ms resolution on Windows, causing fast benchmark
functions to record 0 ns elapsed time and fail timing assertions.
time.perf_counter_ns() provides ~100ns resolution on all platforms.

Co-authored-by: Aseem Saxena <aseembits93@users.noreply.github.com>
@aseembits93 aseembits93 merged commit 506eb44 into main Mar 18, 2026
26 checks passed
@aseembits93 aseembits93 deleted the fix/git-diff-multi-language-extension-filter branch March 18, 2026 00:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants