git-hygiene git-hygiene v1.0.0 · MIT
2026-07-30 / v1.0.0 / SKU: GH-100

git hygiene

Tools don't get co-author credit. Two git hooks, zero dependencies beyond bash/grep/awk/git. Strips AI-attribution trailers. Catches secrets before they land in your object store.

Read the README Releases

NEWELL  /  BUILD. CONNECT. GROW. v1.0.0 · 2026-07-30

Every repo I worked in slowly accumulated Co-Authored-By: Claude and 🤖 Generated with Claude Code trailers in the log. Sometimes the setting got reverted. Sometimes a collaborator's setup differed.

Commit history is the one artifact future employers, acquirers, and collaborators read to evaluate how you work.

You don't credit DeWalt on the shed you built with their drill.

For regulated industries — defense, finance, health — AI-assisted code is becoming a real disclosure question. A clean history sidesteps the question. A dirty one raises it.

commit-msg

Strips AI-attribution trailers

Case-insensitive pattern match on the standard trailer shapes: Co-Authored-By, Generated with, AI-assisted, noreply@anthropic.com. Legitimate human co-authors preserved. Prose mentions of Claude Code as a tool are not touched.

pre-commit

Three-layer secret scan

Layer 1: high-precision regex for known token shapes (AWS, GitHub, OpenAI, Slack). Layer 2: gitleaks if installed (~700 detectors). Layer 3: optional OPSEC content scan for your machine-level identifiers — hostnames, tailnet name, agent handles.

Layer 1
Regex, always on. High-precision patterns for AKIA…, ghp_…, sk-or-…, xox[bp]-…, Bearer, generic key="…". No dependencies. Tight by design — a commit gate that cries wolf gets disabled.
Layer 2
gitleaks, when installed. Drops in automatically if on $PATH. Adds ~700 detectors — Stripe live keys, GCP service account JSON, private keys, database URLs. Missing? Hook warns and falls back to Layer 1.
Layer 3
OPSEC content scan, opt-in. Sources gitignored ~/.config/opsec-patterns.local + ./.opsec-patterns.local. Scans added diff lines for your hostnames, agent handles, tailnet suffixes. Catches what credential regex can't.
~/git-hygiene — per-user setup live
# Clone anywhere stable
$ git clone https://github.com/JordanNewell/git-hygiene.git ~/git-hygiene

# Symlink hooks into your global hooks path
$ mkdir -p ~/.githooks
$ ln -s ~/git-hygiene/hooks/commit-msg ~/.githooks/commit-msg
$ ln -s ~/git-hygiene/hooks/pre-commit  ~/.githooks/pre-commit
$ chmod +x ~/.githooks/*

# Tell git to use that hooks path globally
$ git config --global core.hooksPath ~/.githooks

Optional: brew install gitleaks (macOS) or apt install gitleaks (Debian) to enable Layer 2. See the full install guide for per-repo setup and OPSEC scan configuration.

Capability git-hygiene pre-commit fw GitGuardian CC setting
Strips AI trailers Yes Emits, doesn't strip
Secret scan (regex) Yes Plugin
Secret scan (gitleaks) Auto-detect Plugin Native
OPSEC content scan Yes
Dependencies Bash + grep + awk Python Go binary / SaaS n/a
Telemetry / SaaS None None Optional n/a
I set includeCoAuthoredBy: false already. Do I need this?
Layered defense — the hook catches what slips through. Editor settings get reverted, agent configs drift, collaborators have different setups. The hook is tool-agnostic: it doesn't care which editor or agent emitted the trailer. Three independent layers (editor setting, hook, agent instruction) each fail open independently.
Will it break my test fixtures with realistic fake keys?
No. Path skipping exempts test[s]/, spec/, fixtures/, __tests__/, example[s]/, docs/, *.example, *.template, node_modules/, vendor/, *.min.js. Real secrets live in source and config files, not in fixtures.
Does the hook touch my commit message body?
No — only trailer-shaped lines. Body prose referencing Claude Code as a tool ("the Claude Code agent was mangling whitespace") is preserved. Legitimate human co-authors (Co-Authored-By: Jane Doe <jane@example.com>) are preserved.
Can I opt out per-repo for the OPSEC scan?
Yes: git config opsec.scan disable in any repo. Lives in .git/config — never accidentally committed. Accepts disable, off, false, no, 0. The AI-trailer strip and secret scan are unaffected.
Why bash instead of Python?
Runs on machines without a Python install. The awk is gnarly in places; the test suite is bash-based. Tradeoff: portability over elegance. The hook is small enough (~300 lines across both files) that bash readability isn't the bottleneck.
Can I verify the commits?
Yes. The repo follows PGP-signed commits. Fingerprint: 67567DC5E7C5353F85F2AF0DAC05D3F3E0EFA32A. Run git verify-commit HEAD to confirm.
NEWELL