Skip to content

fix(git): include untracked files in diffs - #250

Merged
404-Page-Found merged 7 commits into
mainfrom
fix/198-detect-untracked-files
Aug 4, 2026
Merged

fix(git): include untracked files in diffs#250
404-Page-Found merged 7 commits into
mainfrom
fix/198-detect-untracked-files

Conversation

@404-Page-Found

@404-Page-Found 404-Page-Found commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Summary

Ensures the single-repository suggestion flow recognizes and analyzes untracked files when no staged changes exist.

Changes

  • Discover non-ignored untracked files with Git.
  • Generate no-index diffs for those files.
  • Combine them with ordinary unstaged changes.
  • Add regression coverage for an untracked-only working tree.

Testing

  • npm run build
  • node --test tests/git-diff.test.mjs

Related

Closes #198

Summary by CodeRabbit

  • Bug Fixes

    • Unstaged diffs now include untracked files and embedded Git repositories.
    • Git operations are more reliable across platforms and handle repository checks consistently.
    • Improved cleanup and error handling during diff generation.
  • Tests

    • Added coverage for untracked files and embedded repositories in unstaged diff results.

Generate no-index diffs for untracked files during unstaged detection.

Closes #198
@coderabbitai

coderabbitai Bot commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It 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 reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Git 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.

Changes

Git diff execution and untracked-file handling

Layer / File(s) Summary
Git executable resolution and invocation
src/git/diff.ts
Git commands resolve an executable across platform-specific locations and use explicit argument arrays. Existing repository, diff, commit, and metadata operations retain their behavior.
Untracked file diff generation
src/git/diff.ts
Unstaged diff generation uses a temporary index with intent-to-add entries, combines tracked and untracked changes, and cleans up temporary resources.
Untracked diff validation
tests/git-diff.test.mjs
Tests verify untracked file content and nested Git repositories with Gitlink mode 160000.

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
Loading

Possibly related PRs

Suggested reviewers: nightcityblade, peter7896, mohammadyusif

Poem

I’m a rabbit with Git in my paws,
New files now show without hidden flaws.
Temporary indexes hop, then depart,
Nested repos leave their mode in the chart.
Safe paths guide each command through,
And tests prove the diff is true.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The Git executable discovery, caching, and command-execution refactor is not required by issue #198. Separate the executable-resolution and command-execution refactor, or document its direct necessity for untracked-file diff detection.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly describes the main change: including untracked files in Git diffs.
Linked Issues check ✅ Passed The implementation includes untracked files and embedded repositories in unstaged diffs, satisfying issue #198.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread src/git/diff.ts Outdated
Comment thread src/git/diff.ts Outdated
Comment thread src/git/diff.ts Fixed
Comment thread src/git/diff.ts Fixed
@404-Page-Found

Copy link
Copy Markdown
Contributor Author

@cubic-dev-ai

@cubic-dev-ai

cubic-dev-ai Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

@cubic-dev-ai

@404-Page-Found I have started the AI code review. It will take a few minutes to complete.

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 2 files

Reply with feedback, questions, or to request a fix.

Fix all with cubic | Re-trigger cubic

Comment thread src/git/diff.ts Outdated
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>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 76c6e18 and e6a96ac.

📒 Files selected for processing (2)
  • src/git/diff.ts
  • tests/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-in node:test for test files in tests/ and tests/e2e/; do not use Jest or Mocha.
Write test assertions with node:assert/strict in test files under tests/ and tests/e2e/.

Files:

  • tests/git-diff.test.mjs
src/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

The project is ESM-only: use .js extensions in local imports and keep verbatimModuleSyntax-compatible TypeScript imports (for example, import type for type-only imports).

Files:

  • src/git/diff.ts
src/git/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Git operations should use execSync/spawnSync rather than simple-git; diff buffering must stay within the 100MB limit, and commits should use temp files via git 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.

See more on https://sonarcloud.io/project/issues?id=404-PF_commit-echo&issues=AZ_MRZ5ghlTIVEJAouZT&open=AZ_MRZ5ghlTIVEJAouZT&pullRequest=250


[warning] 54-54: String.raw should be used to avoid escaping \.

See more on https://sonarcloud.io/project/issues?id=404-PF_commit-echo&issues=AZ_MRZ5ghlTIVEJAouZS&open=AZ_MRZ5ghlTIVEJAouZS&pullRequest=250


[failure] 41-41: Refactor this function to reduce its Cognitive Complexity from 17 to the 15 allowed.

See more on https://sonarcloud.io/project/issues?id=404-PF_commit-echo&issues=AZ_MRZ5ghlTIVEJAouZR&open=AZ_MRZ5ghlTIVEJAouZR&pullRequest=250

🔇 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!

Comment thread src/git/diff.ts Outdated
Comment thread src/git/diff.ts
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>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/git/diff.ts Outdated
Comment thread src/git/diff.ts Outdated
Comment thread src/git/diff.ts
Comment thread src/git/diff.ts Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/git/diff.ts Outdated
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>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/git/diff.ts
Comment thread src/git/diff.ts
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>

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Comment thread src/git/diff.ts Outdated
404-Page-Found and others added 2 commits August 5, 2026 07:33
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>
@sonarqubecloud

sonarqubecloud Bot commented Aug 4, 2026

Copy link
Copy Markdown

@404-Page-Found
404-Page-Found merged commit 3fd0c5d into main Aug 4, 2026
4 checks passed
@404-Page-Found
404-Page-Found deleted the fix/198-detect-untracked-files branch August 4, 2026 21:46
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.

[Reliability] Untracked files are ignored by single-repo diff detection

2 participants