Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions scripts/count_assisted_by.sh
Original file line number Diff line number Diff line change
@@ -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; }