Files
threadx/scripts/count_assisted_by.sh
Frédéric Desbiens f65727f585 Added a script that counts Assisted-by attributions completely (#775)
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) <noreply@anthropic.com>
2026-09-28 12:47:25 -04:00

80 lines
2.7 KiB
Bash
Executable File

#!/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; }