Original Reddit post

I want Claude Code to run git commit, git status, git diff, git add <file> without asking me every time. Zero friction. But git push --force? Blocked. git add -A? Blocked. I’ll do those manually, thanks. Claude Code lets you set allow rules for this. The problem is the deny rules that are supposed to catch dangerous commands don’t work, so you can’t have both. git -C /path reset --hard sails right through with Bash(git reset --hard:*) in your deny rules. The permission system uses prefix matching. It checks if the command starts with the pattern. Any flags before the subcommand (-C, --git-dir, --work-tree) break the match. The * wildcard syntax that should handle this doesn’t work in settings.json. This means you cannot express “deny this subcommand regardless of flags” with deny rules alone. Track it here: #13371 Workaround: a PreToolUse hook in Go that normalizes git commands before checking them. It strips global flags, truncates at shell operators, then matches against a rule table:

  • git add -Adeny (force the LLM to be explicit)
  • git push --forcedeny
  • git pushask
  • git reset --hardask
  • git clean -fask
  • git checkout .ask The hook never returns “allow” — it only denies or asks, so it can’t accidentally bypass the normal permission system. Denied commands return a contextual message telling Claude to pbcopy it for you to run manually. So now you can set generous allow rules while having a safety net. Full writeup with code and setup: adriangalilea.com/claude-code-permission-bypass submitted by /u/Adrian_Galilea

Originally posted by u/Adrian_Galilea on r/ClaudeCode