aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/dot_config
diff options
context:
space:
mode:
Diffstat (limited to 'dot_config')
-rwxr-xr-xdot_config/git/hooks/executable_commit-msg60
1 files changed, 60 insertions, 0 deletions
diff --git a/dot_config/git/hooks/executable_commit-msg b/dot_config/git/hooks/executable_commit-msg
new file mode 100755
index 0000000..78dba63
--- /dev/null
+++ b/dot_config/git/hooks/executable_commit-msg
@@ -0,0 +1,60 @@
+#!/bin/sh
+# Strip Co-authored-by trailers whose identity looks like a coding agent
+# (Copilot, Claude, Codex, ChatGPT, Cursor, Aider, Devin, ...). Various
+# tools — GitHub Copilot CLI, VS Code chat, etc. — append these
+# automatically and they then trip the pre-push hook's agent check.
+# Easier to scrub at commit time than to amend later.
+#
+# Activated via core.hooksPath in ~/.config/git/config so it applies to
+# every repo unless that repo overrides hooksPath itself.
+#
+# Bypass: git commit --no-verify
+
+set -eu
+
+msg_file=$1
+
+# Keep this list in sync with executable_pre-push.
+agent_subs='copilot claude codex chatgpt cursor aider devin [bot] @openai. @anthropic.'
+
+# Rewrite the message file, dropping any Co-authored-by line whose
+# lowercased content contains an agent substring. We deliberately
+# operate line-by-line rather than on trailer blocks because the file
+# already includes git's auto-generated comment block (`# ...`) and we
+# don't want to touch any of that.
+tmp=$(mktemp)
+trap 'rm -f "$tmp"' EXIT INT TERM
+
+awk -v agent_subs="$agent_subs" '
+ BEGIN { n = split(agent_subs, subs, " ") }
+ function is_agent(s, i) {
+ for (i = 1; i <= n; i++) if (index(s, subs[i])) return 1
+ return 0
+ }
+ {
+ # Match the trailer case-insensitively but keep the original
+ # casing for everything we pass through.
+ lower = tolower($0)
+ if (lower ~ /^co-authored-by:[[:space:]]/ && is_agent(lower)) {
+ stripped = 1
+ next
+ }
+ print
+ }
+ END { exit stripped ? 10 : 0 }
+' "$msg_file" >"$tmp" && rc=0 || rc=$?
+
+# awk exits 10 only when we actually dropped a line; anything else is
+# treated as a real error.
+case $rc in
+ 0) exit 0 ;;
+ 10) ;;
+ *) printf 'commit-msg: awk failed (rc=%d); leaving message untouched.\n' "$rc" >&2; exit 0 ;;
+esac
+
+# Collapse any trailing blank lines produced by the removal so we don't
+# leave a dangling blank trailer block.
+sed -e :a -e '/^$/{$d;N;ba' -e '}' "$tmp" >"$msg_file"
+
+printf 'commit-msg: stripped AI Co-authored-by trailer(s).\n' >&2
+exit 0