Skip to content

Commit 62cdad8

Browse files
committed
feat(claude): add 'git commit --no-verify' prompt to git guardrails
1 parent 823e4eb commit 62cdad8

File tree

2 files changed

+60
-1
lines changed

2 files changed

+60
-1
lines changed

claude/hooks/git-guardrails.test.ts

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,49 @@ describe('amend prompting', () => {
185185
})
186186
})
187187

188+
describe('no-verify prompting', () => {
189+
test('prompts for git commit --no-verify', () => {
190+
const { output, exitCode } = runHook(createInput('git commit --no-verify -m "Skip hooks"'))
191+
192+
expect(exitCode).toBe(0)
193+
expect(output?.hookSpecificOutput?.permissionDecision).toBe('ask')
194+
expect(output?.hookSpecificOutput?.permissionDecisionReason).toContain('bypass')
195+
})
196+
197+
test('prompts for git commit with --no-verify and other flags', () => {
198+
const { output, exitCode } = runHook(createInput('git commit -a --no-verify -m "Message"'))
199+
200+
expect(exitCode).toBe(0)
201+
expect(output?.hookSpecificOutput?.permissionDecision).toBe('ask')
202+
})
203+
204+
test('prompts for git commit --no-verify without message', () => {
205+
const { output, exitCode } = runHook(createInput('git commit --no-verify'))
206+
207+
expect(exitCode).toBe(0)
208+
expect(output?.hookSpecificOutput?.permissionDecision).toBe('ask')
209+
})
210+
211+
test('prompts for git commit --no-verify with heredoc', () => {
212+
const command = `git commit --no-verify -m "$(cat <<'EOF'
213+
Test commit message
214+
EOF
215+
)"`
216+
217+
const { output, exitCode } = runHook(createInput(command))
218+
219+
expect(exitCode).toBe(0)
220+
expect(output?.hookSpecificOutput?.permissionDecision).toBe('ask')
221+
})
222+
223+
test('allows regular git commit without --no-verify', () => {
224+
const { output, exitCode } = runHook(createInput('git commit -m "Regular commit"'))
225+
226+
expect(exitCode).toBe(0)
227+
expect(output).toBeNull()
228+
})
229+
})
230+
188231
describe('attribution stripping', () => {
189232
test('strips "Generated with Claude Code" line', () => {
190233
const command = `git commit -m "Test commit

claude/hooks/git-guardrails.ts

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,11 @@
1414
* - Requires explicit confirmation before amending commits
1515
* - Returns ask decision to prompt user
1616
*
17-
* 3. Strips Claude attribution from git commit messages
17+
* 3. Prompts for approval on `git commit --no-verify`
18+
* - Requires explicit confirmation before bypassing repository git hooks
19+
* - Returns ask decision to prompt user
20+
*
21+
* 4. Strips Claude attribution from git commit messages
1822
* - Removes lines containing "generated" (case-insensitive)
1923
* - Removes lines containing "co-authored-by" (case-insensitive)
2024
* - Allows commits to proceed with cleaned messages
@@ -69,6 +73,18 @@ const handler: PreToolUseHandler<BashToolInput> = data => {
6973
}
7074
}
7175

76+
// Prompt for approval on git commit --no-verify
77+
if (/git\s+commit/.test(command) && /--no-verify/.test(command)) {
78+
return {
79+
hookSpecificOutput: {
80+
hookEventName: 'PreToolUse',
81+
permissionDecision: 'ask',
82+
permissionDecisionReason:
83+
'Using --no-verify to bypass repository git hooks. Confirm you want to skip pre-commit checks?',
84+
},
85+
}
86+
}
87+
7288
// Strip Claude attribution from commits
7389
if (/git\s+commit/.test(command)) {
7490
const lines = command.split('\n')

0 commit comments

Comments
 (0)