From bddc14679db1f103bd906987ee31cbac0a83d340 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Desbiens?= Date: Thu, 24 Sep 2026 14:35:08 -0400 Subject: [PATCH] Added a script that counts Assisted-by attributions completely Git reads trailers only from a block at the very end of a commit message. A squash merge concatenates the branch's messages, so every trailer but the last ends up mid-message, and an indented trailer is skipped as well. Both forms are real attributions and both are invisible to the trailer parser, which is what the project has been using to answer which agents touched a file. The script reads whole commit bodies instead. It groups by value, or lists one line per commit with --list, and takes a revision and a path the way git log does. On dev it reports 163 attributions where the trailer parser reports 122, so a quarter of the record was unreachable. The difference is entirely squashed and indented trailers, not new commits. Assisted-by: Claude Code (Opus 5) --- scripts/count_assisted_by.sh | 79 ++++++++++++++++++++++++++++++++++++ 1 file changed, 79 insertions(+) create mode 100755 scripts/count_assisted_by.sh diff --git a/scripts/count_assisted_by.sh b/scripts/count_assisted_by.sh new file mode 100755 index 000000000..57cdf65d2 --- /dev/null +++ b/scripts/count_assisted_by.sh @@ -0,0 +1,79 @@ +#!/bin/bash +############################################################################## +# Copyright (C) 2026 Eclipse ThreadX contributors +# +# This program and the accompanying materials are made available under the +# terms of the MIT License which is available at +# https://opensource.org/licenses/MIT. +# +# AI Disclosure: This file was largely AI-generated by Claude Code (Opus 5). +# The AI-generated portions may be considered public domain (CC0-1.0) +# and not subject to the project's licence. The human contributor has +# reviewed and verified that the code is correct. +# +# SPDX-License-Identifier: MIT and CC0-1.0 +############################################################################## + +# Report the Assisted-by attributions in a repository's history. +# +# scripts/count_assisted_by.sh # HEAD, grouped by value +# scripts/count_assisted_by.sh origin/dev # a branch +# scripts/count_assisted_by.sh origin/dev -- ports # a path +# scripts/count_assisted_by.sh --list origin/dev # one line per commit +# +# Why not git's own trailer parser: git reads trailers only from a block at the +# very end of a message. A squash merge concatenates the branch's commit +# messages, which leaves every trailer but the last one buried mid-message, and +# an indented trailer is skipped as well. Both forms are real attributions and +# both are invisible to --format='%(trailers:key=Assisted-by)'. This reads whole +# commit bodies instead, so the count is complete. + +set -u + +list=0 +if [ "${1:-}" = "--list" ]; then + list=1 + shift +fi + +rev="${1:-}" +if [ -n "$rev" ] && [ "$rev" != "--" ]; then + shift +else + rev="HEAD" +fi + +if [ "${1:-}" = "--" ]; then + shift +fi + +# %x02 opens a record and %x01 separates the hash from the body, so bodies +# containing blank lines survive the pass through awk. +git log "$rev" --format='%x02%H%x01%B' ${1+"$@"} \ + | tr '\n' '\003' | tr '\002' '\n' \ + | awk -F'\001' -v list="$list" ' + NF >= 2 { + body = $2 + gsub(/\003/, "\n", body) + n = split(body, line, "\n") + for (i = 1; i <= n; i++) { + if (line[i] ~ /^[[:space:]]*Assisted-by:[[:space:]]*/) { + value = line[i] + sub(/^[[:space:]]*Assisted-by:[[:space:]]*/, "", value) + sub(/[[:space:]]+$/, "", value) + if (value == "") + continue + if (list) + print substr($1, 1, 8) " " value + else + count[value]++ + } + } + } + END { + if (list) + exit + for (value in count) + printf "%6d %s\n", count[value], value + }' \ + | { if [ "$list" -eq 1 ]; then cat; else sort -rn; fi; }