fix(git): include untracked files in one-ref diffs#210
Conversation
Greptile SummaryThis PR teaches Confidence Score: 5/5Safe to merge; the logic is correct and well-tested across all relevant range forms. All findings are P2. The single-ref vs. revset heuristic using No files require special attention. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["hunk diff [range]"] --> B{input.staged?}
B -- yes --> C["Skip untracked files"]
B -- no --> D{input.range set?}
D -- no --> E["Include untracked files\n(plain working-tree diff)"]
D -- yes --> F["git rev-parse --revs-only range"]
F --> G{positiveRevs == 1\nAND negativeRevs == 0?}
G -- yes --> E
G -- no --> C
E --> H["git status --porcelain=v1 -z\n--untracked-files=all"]
H --> I["Filter: isReviewableUntrackedPath\n(skip dirs, dir-symlinks)"]
I --> J["git diff --no-index /dev/null file\n(synthetic patch per file)"]
J --> K["Append to changeset files"]
C --> L["Return tracked files only"]
Prompt To Fix All With AIThis is a comment left during a code review.
Path: src/core/git.ts
Line: 320-333
Comment:
**Extra `git rev-parse` subprocess on every untracked-file check**
`isWorkingTreeGitDiffInput` spawns a synchronous `git rev-parse --revs-only <range>` subprocess on every call to `listGitUntrackedFiles`. In watch mode `gitWorkingTreeWatchSignature` calls `listGitUntrackedFiles` on each poll tick, so this adds a full extra git process per watch cycle whenever a range is set. The result never changes within a session, so it could be computed once and memoized/passed in rather than re-run every time.
How can I resolve this? If you propose a fix, please make it concise.Reviews (1): Last reviewed commit: "fix(git): include untracked files in one..." | Re-trigger Greptile |
| const revs = runGitText({ | ||
| input, | ||
| args: ["rev-parse", "--revs-only", input.range], | ||
| cwd, | ||
| gitExecutable, | ||
| }) | ||
| .split("\n") | ||
| .map((line) => line.trim()) | ||
| .filter(Boolean); | ||
|
|
||
| const positiveRevs = revs.filter((line) => !line.startsWith("^")); | ||
| const negativeRevs = revs.filter((line) => line.startsWith("^")); | ||
|
|
||
| return positiveRevs.length === 1 && negativeRevs.length === 0; |
There was a problem hiding this comment.
Extra
git rev-parse subprocess on every untracked-file check
isWorkingTreeGitDiffInput spawns a synchronous git rev-parse --revs-only <range> subprocess on every call to listGitUntrackedFiles. In watch mode gitWorkingTreeWatchSignature calls listGitUntrackedFiles on each poll tick, so this adds a full extra git process per watch cycle whenever a range is set. The result never changes within a session, so it could be computed once and memoized/passed in rather than re-run every time.
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/core/git.ts
Line: 320-333
Comment:
**Extra `git rev-parse` subprocess on every untracked-file check**
`isWorkingTreeGitDiffInput` spawns a synchronous `git rev-parse --revs-only <range>` subprocess on every call to `listGitUntrackedFiles`. In watch mode `gitWorkingTreeWatchSignature` calls `listGitUntrackedFiles` on each poll tick, so this adds a full extra git process per watch cycle whenever a range is set. The result never changes within a session, so it could be computed once and memoized/passed in rather than re-run every time.
How can I resolve this? If you propose a fix, please make it concise.There was a problem hiding this comment.
Good catch. I cached the range classification per repo/range so watch-mode polls no longer spawn an extra git rev-parse once the one-ref vs revset decision has been computed.
This comment was generated by Pi using OpenAI o3
Summary
hunk diff <ref>still compares the live working tree against a single refa..b,a...b, andHEAD^!commit-to-commit onlyTesting
bun run typecheckbun test src/core/loaders.test.ts -t "includes untracked files when diff compares the working tree against one ref|excludes untracked files for explicit git ranges that do not include the working tree|excludes untracked files for revset diffs like HEAD^! that do not include the working tree"bun test src/core/watch.test.tsThis PR description was generated by Pi using OpenAI o3