Fix incremental update leaving stale nodes after a file rename#686
Open
thejesh23 wants to merge 1 commit into
Open
Fix incremental update leaving stale nodes after a file rename#686thejesh23 wants to merge 1 commit into
thejesh23 wants to merge 1 commit into
Conversation
get_changed_files() used 'git diff --name-only', which reports a rename a.py -> b.py as only the new path b.py. incremental_update() therefore never saw a.py, and its purge loop (which only removes paths present in the changed/dependent set and missing on disk) left a.py's File/Function/ Class nodes and all edges keyed to it in the graph. The result diverged from a full rebuild, which drops the old path. Switch to 'git diff --name-status -z' and parse it so renames/copies emit BOTH the old and new path. The old path is then seen by the existing purge loop and removed, making an incremental update equal a full rebuild. Adds a unit test for the name-status parser and a real-git integration test asserting the renamed-away source is purged and node/edge/file counts match a fresh full_build.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Linked issue
Closes #684
What & why
get_changed_files()discovered changes withgit diff --name-only, which reports a renamea.py → b.pyas only the new pathb.py.incremental_update()therefore never sawa.py, and its purge loop only removes paths that are in the changed/dependent set and missing on disk — the old path is in neither. Unlikefull_build()(which purgesexisting_files - current_abs), the incremental path had no "purge files no longer on disk" step, so the renamed-away file's File/Function/Class nodes and every edge keyed to it survived. The incremental graph diverged from a full rebuild.This switches change discovery to
git diff --name-status -zand adds_parse_name_status_z(), which emits both the old and new path for rename/copy (R/C) records. The old path then flows through the existing purge loop and is removed, so an incremental update again equals a full rebuild. The--cachedfallback branch gets the same treatment. The now-unused_decode_nul_paths()helper is removed.How it was tested
New tests (both fail on
main, pass here):test_incremental.py::TestGitOperations::test_get_changed_files_reports_both_rename_paths— unit test of the name-status parser.test_integration_git.py::test_incremental_update_purges_renamed_source— real-git test asserting the renamed-away source is purged and node/edge/file counts match a freshfull_build.Checklist
uv run pytest tests/ --tb=short -q(one pre-existing, unrelated Windows/py3.14 failure)uv run ruff check code_review_graph/uv run mypy code_review_graph/incremental.py --ignore-missing-imports --no-strict-optional