Skip to content

fix(hooks): guard-git.sh commit edit-log check falls back to HOOK_CWD too - #2581

Merged
carlos-alm merged 1 commit into
mainfrom
fix/issue-2526
Aug 19, 2026
Merged

fix(hooks): guard-git.sh commit edit-log check falls back to HOOK_CWD too#2581
carlos-alm merged 1 commit into
mainfrom
fix/issue-2526

Conversation

@carlos-alm

Copy link
Copy Markdown
Contributor

Summary

  • .claude/hooks/guard-git.sh's commit edit-log check resolves the target repo via detect_work_dir commit, which only finds an explicit -C <dir>/cd <dir> && in the command text. A bare git commit <files> -m "msg" that relies on a cd from an earlier, separate Bash tool call leaves WORK_DIR empty, and the check silently fell back to the hook process's own ambient cwd — which can be a completely unrelated repo — instead of the payload's reported cwd.
  • This is the same root cause bug(hooks): guard-git.sh branch validation falls back to the session's branch, denying valid subagent pushes to other repos #2386 already fixed for validate_branch_name; this PR applies the identical $HOOK_CWD fallback to the commit edit-log check.
  • Unlike bug(hooks): guard-git.sh branch validation falls back to the session's branch, denying valid subagent pushes to other repos #2386's branch-validation bug, this doesn't produce a false deny: resolving against the wrong repo means git diff --cached --name-only comes back empty there, hitting the existing "no staged files" early-out and silently allowing — so the symptom is the edit-log check getting silently skipped, not a valid commit getting wrongly blocked.
  • Kept docs/examples/claude-code-hooks/guard-git.sh byte-identical to .claude/hooks/guard-git.sh, as enforced by tests/unit/hook-guard-git-clean.test.ts.

Closes #2526

Test plan

  • New tests/unit/hook-guard-git-commit-cwd-fallback.test.ts (4 tests): payload cwd catches an unedited staged file when the ambient cwd is a different, clean repo; still allows when every staged file was actually edited; explicit -C still wins over payload cwd; falls back to silently allowing (not denying) when no payload cwd is available either.
  • Revert-verify: temporarily disabled the fix (if false && ...) and confirmed the main regression test fails with the exact silent-allow bug the issue describes (AssertionError: expected undefined to be 'deny'); restored the fix and all 4 tests pass again.
  • Full guard-git suite: 79/79 tests pass (hook-guard-git-clean.test.ts, hook-guard-git-ifs-bypass.test.ts, hook-guard-git-branch-validation.test.ts, plus the new file) — confirms the byte-identical-copies check still holds.
  • bash -n syntax check on the modified hook.
  • npm run lint clean.
  • Full npx vitest run: 5518/5518 tests pass (344 test files).

… too

Same root cause #2386 fixed for validate_branch_name: a bare
git commit <files> -m "msg" relying on the Bash tool's persistent cwd
from an earlier, separate tool call leaves WORK_DIR empty, and the
commit edit-log check fell back to the hook process's own ambient cwd
instead of the payload's reported cwd -- resolving against a
completely unrelated repo.

Milder than #2386's bug: the wrong repo's git diff --cached comes back
empty, hitting the existing "no staged files" early-out and silently
allowing, rather than wrongly denying. But it means the edit-log
protection (catching another session's files sneaking into your
commit) doesn't actually run when it should.

Applies the same HOOK_CWD fallback to this section, keeping
.claude/hooks/guard-git.sh and docs/examples/claude-code-hooks/guard-git.sh
byte-identical per the existing hook-guard-git-clean.test.ts check.

Closes #2526
@greptile-apps

greptile-apps Bot commented Aug 19, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

The PR makes commit edit-log validation use the Bash payload’s reported cwd when the command has no explicit repository directory, matching the existing branch-validation fallback.

  • Applies the fallback to both the live hook and its byte-identical documentation copy.
  • Adds regression coverage for unauthorized and authorized staged files, explicit git -C precedence, and unavailable payload cwd.

Confidence Score: 5/5

The PR appears safe to merge, with the targeted cwd fallback and synchronized hook copies adequately covered by regression tests.

The fallback is used only when command-text target detection is unresolved, validates that the payload cwd exists, and leaves explicit repository selection in control.

Important Files Changed

Filename Overview
.claude/hooks/guard-git.sh Adds the payload-cwd fallback after explicit target detection while preserving explicit -C precedence and unresolved-target behavior.
docs/examples/claude-code-hooks/guard-git.sh Mirrors the live hook change exactly, preserving the repository’s synchronization contract.
tests/unit/hook-guard-git-commit-cwd-fallback.test.ts Provides focused regression coverage for the corrected fallback, success path, explicit-directory precedence, and missing-cwd behavior.

Reviews (1): Last reviewed commit: "fix(hooks): guard-git.sh commit edit-log..." | Re-trigger Greptile

@carlos-alm
carlos-alm merged commit 6a24aae into main Aug 19, 2026
59 of 63 checks passed
@carlos-alm
carlos-alm deleted the fix/issue-2526 branch August 19, 2026 00:52
@github-actions github-actions Bot locked and limited conversation to collaborators Aug 19, 2026
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

chore(hooks): guard-git.sh's commit edit-log check has the same unresolved-cwd gap as #2386's branch validation

1 participant