Skip to content

Instantly share code, notes, and snippets.

@overengineer
Last active November 10, 2022 15:31
Show Gist options
  • Save overengineer/2f13aae602193d39caac2ba2cc3f46cc to your computer and use it in GitHub Desktop.
Save overengineer/2f13aae602193d39caac2ba2cc3f46cc to your computer and use it in GitHub Desktop.
git contributor stats
#!/bin/bash
set -euo pipefail
MSYS_NO_PATHCONV=0
COL=9
if [[ $# -eq 1 ]]; then
COL=$1
fi
header="email commits blames changes insertions deletions total days active-days active-days(%) changes/week commits/week changes/commit"
words=( $header )
echo "Scan blames"
blames=$(git ls-files --directory src | xargs -n1 git blame --line-porcelain 2> /dev/null | sed -n 's/^author-mail //p' | sort -f | uniq -ic | sort -nr || echo '')
function blame()
{
grep "$1" <(echo "$blames") || printf 0
}
echo "Find Initial Commiter"
read -r initial_commiter <<<"$(git rev-list --max-parents=0 HEAD --format='%aE' | tail -n 1)"
echo "$initial_commiter"
echo "Analyse Initial Commit"
read -r init_changes init_insertions <<<$(git log --numstat --max-parents=0 | awk 'NF' | awk '{insertions+=$1} END {printf "%d %d", NR, insertions }') # edits
echo "Git Contributions"
function contrib () {
git shortlog -sne --all | awk '{seen[$NF]+=$1} END {for(i in seen) print seen[i], i}' | while read -r commits name; do
printf "%s, %s" $(echo $name|tr -d "<" |tr -d ">") $commits # commits
printf ' '
blame "$name" | awk '{printf "%d", $1}'
printf ' '
if [ "<$initial_commiter>" = "$name" ]; then
git log --pretty=format:'' --numstat --author $name | awk 'NF' \
| awk -v ch="$init_changes" -v ins="$init_insertions" '{insertions+=$1; deletions+=$2} END {printf "%d %d %d %d", NR-ch, insertions - ins, deletions, NR+insertions+deletions-ins-ch }' # edits
else
git log --pretty=format:'' --numstat --author $name | awk 'NF' | awk '{insertions+=$1; deletions+=$2} END {printf "%d %d %d %d", NR, insertions, deletions, NR+insertions+deletions }' # edits
fi
printf ' '
git log --format="%ad" --date="unix" --author $name | sed -e 1b -e '$!d' | xargs | awk '{ s = $2 > 0 ? ($1 - $2 )/(24*3600) : 0; printf "%.0f", s }' # total days
printf ' '
printf '%d' $(git log --pretty=format:'%ad' --date=iso --author $name | awk '{print $1}' |sort | uniq | wc -l) # active days
printf '\n'
done | tr -d , | awk '$8 > 0 {printf "%s %.0f %.0f %.0f %.0f\n", $0, (100 * ($9/ ($8 + 0.01))), (7 * $7/($8+0.01)), (7 * $2/($8+0.01)), ($7/($2+0.01))}' | sort -brnk$COL,$COL
}
cat <(seq -s " " ${#words[@]}) <(echo "$header") <(contrib) | head | column -t
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment