Skip to content

fix(incremental): fall back to mtime when stale last_indexed_sha exists — closes #117#125

Merged
Wolfvin merged 1 commit into
mainfrom
fix/redteam-117-find-changed-files-git-fallback
Jul 1, 2026
Merged

fix(incremental): fall back to mtime when stale last_indexed_sha exists — closes #117#125
Wolfvin merged 1 commit into
mainfrom
fix/redteam-117-find-changed-files-git-fallback

Conversation

@Wolfvin

@Wolfvin Wolfvin commented Jul 1, 2026

Copy link
Copy Markdown
Owner

What

Fixes RED TEAM issue #117: find_changed_files() silently returned empty (changed=[], new=[], deleted=[]) on non-git workspaces that had a stale last_indexed_sha bookmark in the DB, causing incremental scan to miss file modifications.

Root cause

find_changed_files() in scripts/incremental.py tried the git-aware path first. If a last_indexed_sha bookmark existed in the DB (from a previous scan when the workspace was a git repo), it called _git_changed() and _git_untracked(). Both return [] when:

  • (a) there are no changes, OR
  • (b) the workspace is not a git repo / git unavailable

The two cases are indistinguishable, so on a non-git workspace with a stale SHA, the function returned empty lists without falling back to the mtime path.

Fix

After retrieving last_indexed_sha, verify the workspace is still a git repo by calling get_current_sha(). If it returns None (workspace is not a git repo or git unavailable), fall through to the mtime-based _find_changed_files_mtime() path instead of trusting the empty git result.

last_sha = _git_last_sha(workspace, db_path)
if last_sha:
    # Issue #117: verify the workspace is STILL a git repo before
    # trusting the git-diff result.
    current_sha = _git_current_sha(workspace)
    if current_sha is None:
        # Workspace is no longer a git repo (or git unavailable).
        # Fall through to mtime path so changes are still detected.
        logger.debug(...)
    else:
        # ... existing git-diff logic ...
        return changed_abs, [], deleted_rel

Verification

Reproduced the bug from #117 and verified the fix:

# 1. Copy clean_app fixture to temp dir (non-git workspace)
# 2. Run full scan (creates DB)
# 3. Inject stale last_indexed_sha into registry_meta
# 4. Modify src/utils.py
# 5. Run incremental scan

# Before fix: changed_files_count: 0  (BUG)
# After fix:  changed_files_count: 1  (correct)

All 6 previously-failing test_graph_incremental.py tests now pass:

  • test_renamed_function_reflected_in_graph
  • test_added_function_reflected_in_graph
  • test_removed_function_reflected_in_graph
  • test_graph_has_no_orphan_edges_after_removal
  • test_incremental_scan_with_modification_updates_graph
  • test_auto_scans_on_fresh_workspace

Test plan

Risk

Low. The fix only adds a git-repo verification check before trusting git-diff results. If the workspace IS a git repo, behavior is unchanged. If it's NOT a git repo, we now correctly fall back to mtime instead of silently returning empty.

…ts — closes #117

Bug: find_changed_files() in scripts/incremental.py tried the git-aware
path first. If a last_indexed_sha bookmark existed in the DB (from a
previous scan when the workspace was a git repo), it called
_git_changed() and _git_untracked(). Both return [] when:
  (a) there are no changes, OR
  (b) the workspace is not a git repo / git unavailable
— the two cases are indistinguishable.

Result: on a non-git workspace with a stale last_indexed_sha, incremental
scan returned (changed=[], new=[], deleted=[]) without falling back to
the mtime path. File modifications were silently missed.

Fix: after retrieving last_indexed_sha, verify the workspace is still a
git repo by calling get_current_sha(). If it returns None (workspace is
not a git repo or git unavailable), fall through to the mtime-based
_find_changed_files_mtime() path instead of trusting the empty git
result.

Verified: incremental scan now correctly detects file modifications on
non-git workspaces with a stale last_indexed_sha bookmark
(changed_files_count: 1 instead of 0). All 6 previously-failing
test_graph_incremental tests now pass.
@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.

@sonarqubecloud

sonarqubecloud Bot commented Jul 1, 2026

Copy link
Copy Markdown

@Wolfvin Wolfvin merged commit 3c441cd into main Jul 1, 2026
5 of 11 checks passed
@Wolfvin Wolfvin deleted the fix/redteam-117-find-changed-files-git-fallback branch July 1, 2026 04:56
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.

1 participant