Skip to content

Fix/git checkout positional args#32

Merged
kenryu42 merged 10 commits intomainfrom
fix/git-checkout-positional-args
Mar 13, 2026
Merged

Fix/git checkout positional args#32
kenryu42 merged 10 commits intomainfrom
fix/git-checkout-positional-args

Conversation

@kenryu42
Copy link
Owner

@kenryu42 kenryu42 commented Mar 13, 2026

Summary

  • Fix git checkout positional args parser to correctly handle known no-value options, options with required values, and options with optional values — preventing false negatives where git checkout <ref> <pathspec> was incorrectly allowed
  • Add comprehensive test coverage for checkout option parsing edge cases
  • Move dist/ build & auto-stage from pre-push to pre-commit hook and simplify setup-hooks script

Changes

Core rule fix (src/core/rules-git.ts)

  • Added CHECKOUT_OPTS_WITH_VALUE set for options that always consume the next token (e.g. -B, --orphan, --conflict, --inter-hunk-context, --pathspec-from-file, --unified)
  • Added CHECKOUT_OPTS_WITH_OPTIONAL_VALUE set for options that may or may not consume a value (e.g. --recurse-submodules, --track)
  • Added CHECKOUT_KNOWN_OPTS_NO_VALUE set for all boolean/flag-only options (e.g. --quiet, --force, --detach, --merge, --patch, --guess, --overlay, etc.)
  • Reworked getCheckoutPositionalArgs() to correctly classify tokens using these sets, so that git checkout --no-quiet main file.txt is properly detected as having two positional args and blocked

Tests

  • tests/core/rules-git.test.ts — Added tests for --no-quiet, --guess, --recurse-submodules (with and without =value), --no-recurse-submodules, --inter-hunk-context, and unknown long option cases
  • tests/core/analyze/parsing-helpers.test.ts — Added unit tests for _getCheckoutPositionalArgs covering known no-value options, optional-value options, required-value options, and unknown option handling

CI / Hooks

  • .husky/pre-commit — Now runs bun run build and auto-stages dist/ if changed (moved from pre-push)
  • .husky/pre-push — Removed entirely (replaced by pre-commit build step)
  • package.json — Simplified setup-hooks script to just chmod +x .husky/pre-commit .husky/pre-push

Documentation

  • README.md — Added git checkout <ref> <path> to the blocked commands table with a note about Git ref vs pathspec disambiguation

Screenshots

N/A — CLI-only changes, no visual UI.

Testing

bun run check

Related Issue

N/A

PR Checklist

  • I have read the CONTRIBUTING.md
  • Code follows project conventions (type hints, naming, etc.)
  • bun run check passes (lint, types, dead code, rules, tests)
  • Tests added for new rules (minimum 90% coverage required)
  • Tested locally with Claude Code, OpenCode, Gemini CLI or GitHub Copilot CLI
  • Updated documentation if needed (README, AGENTS.md)
  • No version changes in package.json

Summary by CodeRabbit

  • Chores

    • Pre-commit now runs checks then build and will stage generated dist files; pre-push no longer runs build/auto-commit. Hook setup simplified.
  • New Features

    • Broader git checkout validation: recognizes more long-option variants and treats ambiguous ref/path cases more conservatively.
  • Documentation

    • Added note blocking a risky git checkout pattern.
  • Tests

    • Expanded checkout parsing coverage and added pre-commit hook integration tests.

Add --inter-hunk-context to options-with-value set and expand
checkout known options with --no-* variants. Fix unknown long
option handling to not consume following tokens, preventing
false negatives in ambiguous ref/path detection.
Add tests for --inter-hunk-context, --no-* options, and verify
unknown long options do not consume subsequent tokens.
Add unit tests for shell parsing helpers, rm flags detection,
find delete patterns, dangerous text detection, xargs child
command extraction, and parallel command parsing.
…ds table

Document that 'git checkout <ref> <path>' may overwrite working tree
when Git disambiguates ref vs pathspec, matching the parser fix.
- Add set -e to pre-commit for better error handling
- Move bun run build and dist staging logic from pre-push to pre-commit
- Simplify setup-hooks script to only set executable permissions
@coderabbitai
Copy link

coderabbitai bot commented Mar 13, 2026

📝 Walkthrough

Walkthrough

Pre-commit split into explicit steps (knip → lint-staged → build) and conditionally stages dist/; pre-push no longer performs build/auto-commit. Git checkout parsing recognizes additional long options and tightens unknown-option handling. Tests and README updated to reflect these behaviors.

Changes

Cohort / File(s) Summary
Git hooks & package script
.husky/pre-commit, .husky/pre-push, package.json
Pre-commit now runs knip, lint-staged, then bun run build, checks dist/ and stages it (git add -A dist/) if changed. Pre-push removed build/auto-commit steps. setup-hooks script simplified to chmod +x existing hooks.
Git checkout parsing logic
src/core/rules-git.ts
Added --inter-hunk-context to value-taking checkout options and many documented no-value long options (e.g., --no-quiet, --no-recurse-submodules, --guess, etc.). Simplified unknown long-option handling to advance by one token to avoid hiding ambiguous ref/path tokens.
Parsing & rules tests
tests/core/analyze/parsing-helpers.test.ts, tests/core/rules-git.test.ts
Expanded tests covering no-value vs value-taking long options, added cases for --no-quiet, --guess, --no-recurse-submodules, --inter-hunk-context, and adjusted expectations for unknown long-option behavior with pathspecs.
Pre-commit integration tests
tests/scripts/pre-commit.test.ts
New integration-style tests that run the pre-commit hook in isolated repos with a fake bun in PATH; assert that untracked/modified dist/ files are staged (A/M) by the hook.
Docs
README.md
Added blocked git command pattern: git checkout <ref> <path> with note about potential ref vs pathspec disambiguation.

Sequence Diagram(s)

mermaid
sequenceDiagram
participant Dev as Developer
participant Hook as Husky (.husky/pre-commit)
participant Bun as Bun (scripts)
participant Knip as knip
participant Lint as lint-staged
participant GitWT as Git (working tree)

Dev->>Hook: git commit (pre-commit)
Hook->>Bun: execute pre-commit script
Bun->>Knip: run knip
Knip-->>Bun: result
Bun->>Lint: run lint-staged
Lint-->>Bun: result
Bun->>Bun: run build (bun run build)
Bun->>GitWT: check dist/ status
alt dist/ changed
Bun->>GitWT: git add -A dist/
end
Bun-->>Hook: exit (success/fail)

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hopped through hooks and split the old chain,

I taught checkout flags their proper name,
I built the build and staged the little dist,
A tidy hop — no step was missed,
Cheers from a rabbit for tests that tame the game.

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: fixing git checkout positional arguments parsing, which is the core technical issue addressed throughout the changeset.
Description check ✅ Passed The PR description is comprehensive and well-structured. It includes a clear summary, detailed changes across all modified files, testing instructions, and a completed checklist matching the template requirements.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/git-checkout-positional-args
📝 Coding Plan
  • Generate coding plan for human review comments

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 and usage tips.

@codecov
Copy link

codecov bot commented Mar 13, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 99.53%. Comparing base (63e4b7f) to head (d5f9ab6).
⚠️ Report is 11 commits behind head on main.

Additional details and impacted files
@@           Coverage Diff           @@
##             main      #32   +/-   ##
=======================================
  Coverage   99.53%   99.53%           
=======================================
  Files          50       50           
  Lines        4528     4540   +12     
=======================================
+ Hits         4507     4519   +12     
  Misses         21       21           

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@greptile-apps
Copy link

greptile-apps bot commented Mar 13, 2026

Greptile Summary

This PR fixes a false-negative bug in getCheckoutPositionalArgs() where an unknown long option (e.g., --unknown) would silently consume the next token as its "value", allowing git checkout --unknown ref pathspec to slip through as a single-positional-arg command. The fix flips to a fail-safe posture: unknown long options now advance by just one token, so both ref and pathspec are counted and the command is correctly blocked.

Key changes:

  • getCheckoutPositionalArgs() — unknown long options no longer skip their presumed next-token value; only documented options in the three opt-sets consume tokens.
  • CHECKOUT_KNOWN_OPTS_NO_VALUE — expanded with all missing --no-* negation forms (--no-quiet, --no-force, --no-detach, --no-merge, --no-patch, --no-recurse-submodules, etc.) and new flags (--guess, --overlay, --ignore-skip-worktree-bits, --pathspec-file-nul, …).
  • CHECKOUT_OPTS_WITH_VALUE--inter-hunk-context added (used in patch mode; takes a numeric argument).
  • Pre-commit hook — bun run build and dist/ auto-staging moved from pre-push to pre-commit; git diff --quiet dist/ is used to detect changes before staging. Note: this check only sees modifications to already-tracked files; brand-new untracked files in dist/ would be missed (see inline comment).
  • setup-hooks — simplified to chmod +x; now depends on both hook files being present in the repository.
  • Tests — comprehensive coverage added for every new option category with both unit (_getCheckoutPositionalArgs) and integration (analyzeGit) tests.

Confidence Score: 5/5

  • This PR is safe to merge — the core logic fix is correct, tests are thorough, and no regressions were found.
  • The safety-critical change (fail-safe unknown option handling) is well-reasoned and correctly implemented. Both the unit tests (_getCheckoutPositionalArgs) and integration tests (analyzeGit) cover the new and changed behaviours comprehensively. The hook reorganisation is straightforward. Two minor style issues noted (git diff vs git status for untracked files, and implicit pre-push dependency in setup-hooks) but neither affects correctness.
  • .husky/pre-commit — the git diff --quiet dist/ check misses new untracked dist/ files; and package.json setup-hooks implicitly requires .husky/pre-push to exist.

Important Files Changed

Filename Overview
src/core/rules-git.ts Core fix: unknown long options no longer consume the next token as a value (fail-safe behaviour). New --no-* negation flags and missing boolean flags added to CHECKOUT_KNOWN_OPTS_NO_VALUE; --inter-hunk-context added to CHECKOUT_OPTS_WITH_VALUE. Logic is sound; both known-no-value and unknown branches now correctly fall through to i++, eliminating the false-negative where git checkout --flag ref pathspec was allowed.
tests/core/rules-git.test.ts New tests correctly cover --no-quiet, --guess, --no-recurse-submodules, and --inter-hunk-context; the renamed test for unknown-option behaviour accurately reflects the updated semantics.
tests/core/analyze/parsing-helpers.test.ts New unit tests for _getCheckoutPositionalArgs directly exercise the renamed "unknown long option does not consume value" branch, documented no-value flags, and required-value option consumption. Good coverage of all three option categories.
.husky/pre-commit Build and dist/ auto-staging moved from pre-push to pre-commit. Uses git diff --quiet dist/ to detect working-tree changes; correctly handles the clean+rebuild cycle since dist/ is a tracked directory. Minor edge: newly untracked dist/ files (e.g., on a first-ever build in a fresh worktree) would not be detected, but this is negligible given dist/ is already committed.
package.json setup-hooks simplified to a plain chmod +x on both hook files. Works correctly since hooks are now committed to the repo rather than generated at install time. Correct as long as both files remain in the repository.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A["token = next token\nfrom git checkout args"] --> B{starts with '-'?}
    B -- No --> C["Push to positional[]"]
    B -- Yes --> D{token == '--'?}
    D -- Yes --> E["STOP – break loop"]
    D -- No --> F{in CHECKOUT_OPTS_WITH_VALUE?}
    F -- Yes --> G["i += 2\n(consume option + value)"]
    F -- No --> H{"starts with '--'\nAND contains '='?"}
    H -- Yes --> I["i++\n(skip foo=bar token)"]
    H -- No --> J{in CHECKOUT_OPTS_WITH_OPTIONAL_VALUE?}
    J -- Yes --> K{"nextToken is a\nrecognised mode value?"}
    K -- Yes --> L["i += 2\n(consume option + mode)"]
    K -- No --> M["i++\n(option only)"]
    J -- No --> N{"starts with '--' AND\nnot in CHECKOUT_KNOWN_OPTS_NO_VALUE\nnot in WITH_VALUE\nnot in WITH_OPTIONAL_VALUE?"}
    N -- Yes --> O["i++\n⚠️ FAIL-SAFE: unknown option\ndoes NOT consume next token\n(PR fix)"]
    N -- No --> P["i++\n(known no-value flag,\nor short option)"]

    style O fill:#ffd700,stroke:#b8860b
    style C fill:#90ee90,stroke:#228b22
Loading

Last reviewed commit: 5ccaadf

Comment on lines +9 to +11
if ! git diff --quiet dist/; then
git add -A dist/
fi
Copy link

Choose a reason for hiding this comment

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

git diff only detects changes to already-tracked files

git diff --quiet dist/ compares the working tree to the index (staged content). This means brand-new, previously-untracked files inside dist/ (e.g., after bun run clean wipes the directory in a fresh worktree where dist/ was never committed) will not be detected and therefore won't be auto-staged.

A more robust check would use git status --porcelain dist/, which captures both modified and untracked files:

Suggested change
if ! git diff --quiet dist/; then
git add -A dist/
fi
if [ -n "$(git status --porcelain dist/)" ]; then
git add -A dist/
fi

This is a minor edge case for the typical development workflow where dist/ is already tracked, but worth considering for contributors who clone and build for the first time before committing.

"cc-safety-net": "bun run src/bin/cc-safety-net.ts",
"prepare": "husky && bun run setup-hooks",
"setup-hooks": "bun -e 'await Bun.write(\".husky/pre-commit\", \"#!/usr/bin/env sh\\n\\nbun run knip && bun run lint-staged\\n\")' && chmod +x .husky/pre-commit"
"setup-hooks": "chmod +x .husky/pre-commit .husky/pre-push"
Copy link

Choose a reason for hiding this comment

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

setup-hooks implicitly depends on .husky/pre-push existing

The chmod +x will silently succeed today because .husky/pre-push is still committed, but if the file is ever removed the script will fail. Since the pre-push hook only runs bun run check, it might be intentionally kept minimal — but the dependency is non-obvious. Consider adding a guard or a comment so future maintainers know the file must remain:

Suggested change
"setup-hooks": "chmod +x .husky/pre-commit .husky/pre-push"
"setup-hooks": "chmod +x .husky/pre-commit .husky/pre-push || true"

Using || true makes the prepare lifecycle script resilient to the case where a contributor deletes .husky/pre-push in a follow-up PR, without silently swallowing real errors from the pre-commit chmod.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 2

🧹 Nitpick comments (1)
.husky/pre-commit (1)

4-5: Consider enforcing the full pre-commit quality gate with bun run check.

At Line 4-5, the hook runs partial checks. Using the full check command here keeps local gating consistent.

💡 Suggested adjustment
-bun run knip
 bun run lint-staged
+bun run check
Based on learnings: Run `bun run check` before committing which executes: biome check → typecheck → knip → ast-grep scan → bun test.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In @.husky/pre-commit around lines 4 - 5, Replace the partial pre-commit
commands that only run "bun run knip" and "bun run lint-staged" with a full
quality gate by invoking "bun run check" (which runs biome check → typecheck →
knip → ast-grep scan → bun test) at the start of the hook; update the pre-commit
script so the command sequence includes "bun run check" (and optionally retain
"bun run lint-staged" afterward if staged-only linting should still run) to
ensure the complete suite runs before commits.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In @.husky/pre-commit:
- Around line 9-10: The pre-commit check uses "git diff --quiet dist/" which
misses untracked files; replace the condition so it detects both tracked changes
and new untracked files (e.g., use "git status --porcelain --untracked-files=all
dist/" and check for non-empty output) before running the existing "git add -A
dist/" logic; update the conditional that currently references "git diff --quiet
dist/" to call and test "git status --porcelain --untracked-files=all dist/" (or
an equivalent "git ls-files --others --exclude-standard dist/") so newly
generated files under dist/ are correctly staged.

In `@package.json`:
- Line 30: The "setup-hooks" npm script still references a removed hook file and
will fail when running prepare; update the "setup-hooks" script (the
"setup-hooks" entry in package.json) to stop referencing ".husky/pre-push" —
either remove ".husky/pre-push" so it only chmods ".husky/pre-commit", or change
the command to check for the file's existence before chmod so prepare doesn't
fail on fresh installs.

---

Nitpick comments:
In @.husky/pre-commit:
- Around line 4-5: Replace the partial pre-commit commands that only run "bun
run knip" and "bun run lint-staged" with a full quality gate by invoking "bun
run check" (which runs biome check → typecheck → knip → ast-grep scan → bun
test) at the start of the hook; update the pre-commit script so the command
sequence includes "bun run check" (and optionally retain "bun run lint-staged"
afterward if staged-only linting should still run) to ensure the complete suite
runs before commits.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 635926ac-7953-4cf5-be7c-fe150cd61d36

📥 Commits

Reviewing files that changed from the base of the PR and between 63e4b7f and 5ccaadf.

⛔ Files ignored due to path filters (2)
  • dist/bin/cc-safety-net.js is excluded by !**/dist/**
  • dist/index.js is excluded by !**/dist/**
📒 Files selected for processing (7)
  • .husky/pre-commit
  • .husky/pre-push
  • README.md
  • package.json
  • src/core/rules-git.ts
  • tests/core/analyze/parsing-helpers.test.ts
  • tests/core/rules-git.test.ts
💤 Files with no reviewable changes (1)
  • .husky/pre-push

"cc-safety-net": "bun run src/bin/cc-safety-net.ts",
"prepare": "husky && bun run setup-hooks",
"setup-hooks": "bun -e 'await Bun.write(\".husky/pre-commit\", \"#!/usr/bin/env sh\\n\\nbun run knip && bun run lint-staged\\n\")' && chmod +x .husky/pre-commit"
"setup-hooks": "chmod +x .husky/pre-commit .husky/pre-push"
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

setup-hooks still references .husky/pre-push, which can break prepare.

At Line 30, this will fail on fresh installs if .husky/pre-push was removed in this PR.

💡 Proposed fix
-    "setup-hooks": "chmod +x .husky/pre-commit .husky/pre-push"
+    "setup-hooks": "chmod +x .husky/pre-commit"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
"setup-hooks": "chmod +x .husky/pre-commit .husky/pre-push"
"setup-hooks": "chmod +x .husky/pre-commit"
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@package.json` at line 30, The "setup-hooks" npm script still references a
removed hook file and will fail when running prepare; update the "setup-hooks"
script (the "setup-hooks" entry in package.json) to stop referencing
".husky/pre-push" — either remove ".husky/pre-push" so it only chmods
".husky/pre-commit", or change the command to check for the file's existence
before chmod so prepare doesn't fail on fresh installs.

The previous git diff --quiet approach only detected changes to tracked
files, missing newly generated untracked files in dist/. Using
git status --porcelain --untracked-files=all ensures both modified and
new files are properly detected and staged.
The previous git diff --quiet approach only detected changes to tracked
files, missing newly generated untracked files in dist/. Using
git status --porcelain --untracked-files=all ensures both modified and
new files are properly detected and staged.
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🧹 Nitpick comments (1)
tests/scripts/pre-commit.test.ts (1)

17-77: Align private helper signatures with TS repo conventions.

Module-private helpers should use a leading underscore, and non-mutated command args should be readonly string[] in these helper signatures.

As per coding guidelines: "Use leading underscore for private/internal module functions in TypeScript" and "Use readonly arrays where mutation isn't needed in TypeScript".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/scripts/pre-commit.test.ts` around lines 17 - 77, Rename the
module-private helper functions to use a leading underscore and mark non-mutated
command argument arrays as readonly: change runCommand(args: string[], ...) to
_runCommand(args: readonly string[], ...), runChecked(args: string[], ...) to
_runChecked(args: readonly string[], ...), and similarly rename runPreCommit to
_runPreCommit and distStatus to _distStatus (and createTestRepo to
_createTestRepo if it's intended module-private); update all internal call sites
to the new names and adjust signatures so any functions that accept CLI arg
arrays use readonly string[] rather than string[].
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@tests/scripts/pre-commit.test.ts`:
- Around line 49-52: The test setup calls runChecked to configure git user and
gpg but doesn’t set line-ending config, which causes LF→CRLF warnings on Windows
and makes runChecked’s empty-stderr assertion fail; update the repo setup in
tests/scripts/pre-commit.test.ts where runChecked is invoked to also disable
autocrlf and safecrlf by running git config core.autocrlf false and git config
core.safecrlf false (use the same runChecked helper) so the test repo won’t emit
CRLF conversion warnings.

---

Nitpick comments:
In `@tests/scripts/pre-commit.test.ts`:
- Around line 17-77: Rename the module-private helper functions to use a leading
underscore and mark non-mutated command argument arrays as readonly: change
runCommand(args: string[], ...) to _runCommand(args: readonly string[], ...),
runChecked(args: string[], ...) to _runChecked(args: readonly string[], ...),
and similarly rename runPreCommit to _runPreCommit and distStatus to _distStatus
(and createTestRepo to _createTestRepo if it's intended module-private); update
all internal call sites to the new names and adjust signatures so any functions
that accept CLI arg arrays use readonly string[] rather than string[].

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 7a589232-6c33-4773-a45a-6181550e14ab

📥 Commits

Reviewing files that changed from the base of the PR and between 5ccaadf and 85332f3.

📒 Files selected for processing (2)
  • .husky/pre-commit
  • tests/scripts/pre-commit.test.ts

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
tests/scripts/pre-commit.test.ts (1)

87-122: Consider adding a test for when dist/ has no changes.

The existing tests cover staging of new untracked and modified tracked files. A test verifying that nothing is staged when dist/ is unchanged would complete the coverage matrix.

💡 Suggested test case
test('does not stage when dist is unchanged', () => {
  const { repoDir, env } = createTestRepo();

  mkdirSync(join(repoDir, 'dist'), { recursive: true });
  writeFileSync(join(repoDir, 'dist', 'index.js'), 'console.log("committed");\n');
  runChecked(['git', 'add', '-A'], repoDir, env);
  runChecked(['git', 'commit', '-qm', 'initial'], repoDir, env);

  runPreCommit(repoDir, env);

  expect(distStatus(repoDir, env)).toBe('');
});
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@tests/scripts/pre-commit.test.ts` around lines 87 - 122, Add a new test that
verifies no files are staged when dist/ is unchanged: use createTestRepo() to
get { repoDir, env }, create dist/ and write an initial file (e.g.,
writeFileSync(join(repoDir,'dist','index.js'), 'console.log("committed");\n')),
stage and commit it with runChecked(['git','add','-A'], repoDir, env) and
runChecked(['git','commit','-qm','initial'], repoDir, env), then call
runPreCommit(repoDir, env) and assert distStatus(repoDir, env) returns an empty
string; place this alongside the other tests in the same describe block to
complete coverage for unchanged dist/.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@tests/scripts/pre-commit.test.ts`:
- Around line 87-122: Add a new test that verifies no files are staged when
dist/ is unchanged: use createTestRepo() to get { repoDir, env }, create dist/
and write an initial file (e.g., writeFileSync(join(repoDir,'dist','index.js'),
'console.log("committed");\n')), stage and commit it with
runChecked(['git','add','-A'], repoDir, env) and
runChecked(['git','commit','-qm','initial'], repoDir, env), then call
runPreCommit(repoDir, env) and assert distStatus(repoDir, env) returns an empty
string; place this alongside the other tests in the same describe block to
complete coverage for unchanged dist/.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 756874e5-0fe4-46b3-8db8-5d32cc37aef9

📥 Commits

Reviewing files that changed from the base of the PR and between 85332f3 and 2364043.

📒 Files selected for processing (1)
  • tests/scripts/pre-commit.test.ts

@kenryu42 kenryu42 merged commit fb5ccdd into main Mar 13, 2026
6 checks passed
@kenryu42 kenryu42 deleted the fix/git-checkout-positional-args branch March 13, 2026 09:54
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