Skip to content

fix(status): detect committed source changes with a clean working tree - #1540

Open
WhoJay0609 wants to merge 1 commit into
colbymchenry:mainfrom
WhoJay0609:codex/fix-status-clean-commit-detection
Open

fix(status): detect committed source changes with a clean working tree#1540
WhoJay0609 wants to merge 1 commit into
colbymchenry:mainfrom
WhoJay0609:codex/fix-status-clean-commit-detection

Conversation

@WhoJay0609

Copy link
Copy Markdown

Problem

codegraph status used git status --porcelain to detect pending source changes. That catches uncommitted edits, but it misses changes already committed or introduced by a pull, merge, rebase, or branch checkout.

Once the working tree is clean, status can report that the index is up to date even though the source tree no longer matches the stored index.

Reproduction

This reproduces on CodeGraph 1.5.0:

tmp="$(mktemp -d)"
cd "$tmp"

git init
git config user.email "test@example.com"
git config user.name "Test User"

printf 'def existing_symbol():\n    return 1\n' > app.py
codegraph init .
git add -A
git commit -m "initial indexed state"

printf 'def newly_committed_symbol():\n    return 2\n' > new_feature.py
git add new_feature.py
git commit -m "add new feature"

git status --porcelain
# no output

codegraph status --json
codegraph query newly_committed_symbol

Before this patch, the status output contains:

{"pendingChanges":{"added":0,"modified":0,"removed":0}}

The query does not return newly_committed_symbol. Running codegraph sync detects one added file, and the query succeeds afterward.

With this patch, status stays read-only and reports:

{"pendingChanges":{"added":1,"modified":0,"removed":0}}

Fix

status and sync previously used different freshness checks. getChangedFiles(), which supplies the status counts, read git status. sync() compared the current source tree with the file records stored in the index.

getChangedFiles() now scans the current indexable files and compares them with the stored records. It uses the existing scanner, so ignore rules, explicit includes, custom extensions, and embedded repositories follow the same visibility rules as indexing and sync. For tracked files, size and mtime filter out unchanged files before content hashing.

Removal detection also checks whether an indexed path still exists on disk. This matters because git ls-files can list a tracked file after it has been deleted but before the deletion is staged.

The separate git status detector is removed. Files that are untracked by Git but already indexed by CodeGraph are still compared with their stored records, so unchanged files are not reported as new on every status call.

This change does not alter the database schema, public API, or JSON field names. It does not require a full re-index.

Performance

I measured the complete status --json command on one of our own repositories. CodeGraph saw 1,812 source files with 909,802 physical lines. The benchmark disabled the daemon, ran three warmups, then alternated the baseline and patched commands for 20 measured runs.

CodeGraph 1.5.0 This patch
Mean 253.69 ms 513.51 ms
Median 250.90 ms 511.32 ms
P95 265.71 ms 520.76 ms

The filesystem scan adds about 260 ms on this repository. Files whose size and mtime still match the index are not read or hashed.

The patched run also reported one 2.39 MB generated source file as pending, so each run read and hashed that file. The measured difference is therefore a conservative estimate of the scan-only cost.

Tests

The new tests cover committed additions, modifications, and deletions with a clean working tree. An end-to-end test checks the status --json pending-change count.

npm run build
npx tsc --noEmit
npx vitest run __tests__/sync.test.ts __tests__/status-json.test.ts

The focused run passes all 41 tests, including all 35 tests in sync.test.ts.

A full npm test run on Linux reported 2,891 passing, 178 skipped, and 12 failing tests. The failures are in Git-hook and includeIgnored or nested-repository test files outside this diff. I have not treated the full run as green or claimed that those failures reproduce on the base branch.

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