fix(git): include untracked files in diffs - #250
Conversation
Generate no-index diffs for untracked files during unstaged detection. Closes #198
|
Note Reviews pausedIt looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the Use the following commands to manage reviews:
Use the checkboxes below for quick actions:
📝 WalkthroughWalkthroughGit operations now use a cached, platform-specific executable path and explicit argument arrays. Unstaged diffs now include untracked files and nested Git repositories through temporary-index handling. Tests cover file content and Gitlink mode output. ChangesGit diff execution and untracked-file handling
Estimated code review effort: 4 (Complex) | ~45 minutes Sequence Diagram(s)sequenceDiagram
participant Caller
participant getUnstagedDiff
participant GitExecutable
participant TemporaryIndex
Caller->>getUnstagedDiff: request unstaged diff
getUnstagedDiff->>TemporaryIndex: create temporary index
getUnstagedDiff->>GitExecutable: add untracked paths and generate diff
GitExecutable-->>getUnstagedDiff: tracked and untracked diff
getUnstagedDiff->>TemporaryIndex: clean up temporary resources
getUnstagedDiff-->>Caller: return diff result
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✨ Finishing Touches📝 Generate docstrings
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@codex review |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 23a1bbfe08
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
@404-Page-Found I have started the AI code review. It will take a few minutes to complete. |
There was a problem hiding this comment.
All reported issues were addressed across 2 files
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
Use a temporary index to generate untracked diffs in one Git pass, including embedded repositories without mutating the real index. Resolve Git to an absolute executable path before running commands. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@src/git/diff.ts`:
- Around line 41-84: The resolveGitExecutable function has cognitive complexity
of 17, exceeding the limit of 15. Extract the Windows-specific candidate
collection logic (the if (process.platform === 'win32') block that handles
programFiles and localAppData) into a separate helper function, and extract the
Unix-specific candidate collection logic (the else block with hardcoded paths)
into another separate helper function. Replace these blocks in
resolveGitExecutable with calls to these new helpers that return arrays of
candidates, reducing the nested conditionals and loops in the main function.
- Around line 173-214: Update the untracked-diff aggregation around the
temporary-index diff helper and getUnstagedDiff so the diff produced by git diff
with the temporary index is treated as the complete result when untracked
pathspecs exist, without appending trackedDiff again. Add a regression test
covering one tracked modification plus one untracked file and verify each
tracked hunk appears only once.
🪄 Autofix
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: ASSERTIVE
Plan: Pro Plus
Run ID: 213286cb-3ccd-4cb8-9892-7850065425e2
📒 Files selected for processing (2)
src/git/diff.tstests/git-diff.test.mjs
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
- GitHub Check: cubic · AI code reviewer
🧰 Additional context used
📓 Path-based instructions (3)
tests/**/*.mjs
📄 CodeRabbit inference engine (AGENTS.md)
tests/**/*.mjs: Use Node.js built-innode:testfor test files intests/andtests/e2e/; do not use Jest or Mocha.
Write test assertions withnode:assert/strictin test files undertests/andtests/e2e/.
Files:
tests/git-diff.test.mjs
src/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
The project is ESM-only: use
.jsextensions in local imports and keepverbatimModuleSyntax-compatible TypeScript imports (for example,import typefor type-only imports).
Files:
src/git/diff.ts
src/git/**/*.ts
📄 CodeRabbit inference engine (AGENTS.md)
Git operations should use
execSync/spawnSyncrather thansimple-git; diff buffering must stay within the 100MB limit, and commits should use temp files viagit commit -F.
Files:
src/git/diff.ts
🪛 ast-grep (0.45.0)
src/git/diff.ts
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
[warning] Importing child_process exposes a command-execution surface; ensure any command/argument built from input is validated, and prefer execFile/spawn with an argument array over exec.
Context: import { execFileSync, spawnSync } from 'node:child_process';
Note: [CWE-78] Improper Neutralization of Special Elements used in an OS Command ('OS Command Injection').
(detect-child-process-typescript)
🪛 GitHub Check: SonarCloud
src/git/diff.ts
[notice] 72-72: OS commands should not rely on PATH resolution
Make sure the "PATH" variable only contains fixed, unwriteable directories.See more on SonarQube Cloud
[notice] 87-87: OS commands should not rely on PATH resolution
Make sure the "PATH" variable only contains fixed, unwriteable directories.See more on SonarQube Cloud
🪛 GitHub Check: SonarCloud Code Analysis
src/git/diff.ts
[warning] 61-61: Do not call Array#push() multiple times.
[warning] 54-54: String.raw should be used to avoid escaping \.
[failure] 41-41: Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed.
🔇 Additional comments (2)
src/git/diff.ts (1)
1-40: LGTM!Also applies to: 85-172, 219-269
tests/git-diff.test.mjs (1)
193-237: LGTM!
Use the temporary-index diff as the complete unstaged result when untracked paths are present, and cover mixed tracked and untracked changes. Split Git executable candidate discovery into focused helpers and use only fixed installation locations. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Reply with feedback, questions, or to request a fix.
Fix all with cubic | Re-trigger cubic
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
Scope temporary-index diffs to untracked paths, preserve literal filenames, and bound batched Git output. Restore absolute execution for Git installations discovered through relative or custom PATH entries. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed across 2 files (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
Keep the temp-index diff scoped to untracked pathspecs while preserving literal filename handling and buffered Git execution. This prevents duplicate tracked hunks and argv growth in mixed diff cases. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
There was a problem hiding this comment.
All reported issues were addressed across 1 file (changes from recent commits).
Tip: Review your code locally with the cubic CLI to iterate faster.
Fix all with cubic | Re-trigger cubic
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Keep Git execution on resolved absolute paths, but let PATH candidates win ahead of fixed fallbacks so environment-managed Git installs behave normally. The untracked diff batching remains unchanged. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
|



Summary
Ensures the single-repository suggestion flow recognizes and analyzes untracked files when no staged changes exist.
Changes
Testing
npm run buildnode --test tests/git-diff.test.mjsRelated
Closes #198
Summary by CodeRabbit
Bug Fixes
Tests