Skip to content

Instantly share code, notes, and snippets.

@nilium nilium/git-instat
Last active May 20, 2019

Embed
What would you like to do?
Git script to scan diff --numstat output and sum it.
#!/bin/bash
usage() {
cat >&2 <<-'EOF'
Usage: git-instat [range] [path...] [-path pattern...] [-only pattern...] [-omit pattern...]
Print a stat summary for the given paths in a ref.
If no range is given, the default is 'HEAD^1..HEAD'.
-only and -omit may be passed to filter lines of the numstat, such that
only lines containing none of the omitted patterns and all of the 'only'
patterns are the only remaining outputs.
-path arguments are any path pattern accepted by git-diff(1).
EOF
exit 2
}
var=paths
paths=()
only=()
omit=()
ref='HEAD^1..HEAD'
case "${1---}" in
-h|--help) usage;;
-path|-omit|-only) :;;
--) shift;;
*) ref="$1"; shift;;
esac
set -e
push() {
local var="$1"
shift
for arg; do
eval "${var}"'[${#'"${var}"'[@]}]="$arg"'
done
}
noswitch=
for arg; do
shift
case "${noswitch}${arg}" in
-only) var=only; noswitch=x;;
-omit) var=omit; noswitch=x;;
-path) var=paths; noswitch=x;;
*)
push "$var" "$arg"
noswitch=
;;
esac
done
if [ ${#paths[@]} -gt 0 ]; then
paths=(-- "${paths[@]}")
fi
recurse() {
cmd=()
for arg; do
shift
if [ "$arg" = -- ]; then
break
fi
push cmd "$arg"
done
if [ $# -eq 0 ]; then
cat
else
local arg="$1"
shift
"${cmd[@]}" "$arg" | recurse "${cmd[@]}" -- "$@"
fi
}
git diff --numstat "$ref" "${paths[@]}" |
recurse grep --line-buffered -ve -- "${omit[@]}" |
recurse grep --line-buffered -e -- "${only[@]}" |
awk -F $'\t' '
BEGIN { added = deleted = 0 }
{ added += $1; deleted += $2; print $0 }
END { printf "%d\t%d\n", added, deleted }
'
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.