Last active
November 18, 2020 05:01
-
-
Save zambonin/d9398232a694176e1f664521e38a7ef9 to your computer and use it in GitHub Desktop.
Estimates how much time a project has taken according to the commit timeline.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env sh | |
# shellcheck disable=SC2214 | |
# | |
# A POSIX-compliant shell script that estimates the number of hours taken to | |
# create the contents of a Git repository. The heuristic is based on grouping | |
# bundles of commits according to a certain period limit, accumulating time | |
# differences between pairs of commits in each bundle, and compensating for its | |
# first commit with another parametrized quantity. Timestamps are taken from | |
# the author of the commit. | |
# | |
# It accepts three options to customize its behavior, described as follows. The | |
# last argument must be a valid Git folder, with the current folder as default. | |
# | |
# -f, --first-delay=<amount> | |
# Consider that the first commit of each bundle took <amount> seconds | |
# to create. The default value is 1800, i.e. half an hour. Note that | |
# this must be smaller or equal than the amount set by -g, such that | |
# the bundles do not overlap. | |
# | |
# -g, --group-period=<amount> | |
# Create a new bundle of commits when the difference between two | |
# timestamps is greater than <amount> seconds. The default value is | |
# 7200, or two hours. | |
# | |
# -p, --pass-options=<options> | |
# Pass options to git-log(1). Suggested options are | |
# --author/--committer, --since/--until, --no-merges etc. | |
# | |
# Parsing of long options is adapted from https://stackoverflow.com/a/28466267. | |
FIRST_DELAY=1800 | |
GROUP_TIME=7200 | |
OTHER_OPT="--" | |
while getopts f:g:p:-: OPT ; do | |
if [ "$OPT" = "-" ] ; then | |
OPT="${OPTARG%%=*}" | |
OPTARG="${OPTARG#$OPT}" | |
OPTARG="${OPTARG#=}" | |
fi | |
case "$OPT" in | |
f | first-delay ) FIRST_DELAY="${OPTARG:-$FIRST_DELAY}" ;; | |
g | group-period ) GROUP_TIME="${OPTARG:-$GROUP_TIME}" ;; | |
p | pass-options ) OTHER_OPT="${OPTARG:-$OTHER_OPT}" ;; | |
??* ) exit 1 ;; | |
\? ) exit 2 ;; | |
esac | |
done | |
shift $((OPTIND - 1)) | |
FOLDER="${1:-.}" | |
: $((DIFF=GROUP_TIME - FIRST_DELAY)) | |
if [ ! -d "${FOLDER}/.git" ] || [ $((DIFF)) -lt 0 ] ; then | |
cat <<-EOF | |
Usage: sh ${0##*/} [options] [folder] | |
-f, --first-delay=<seconds> | |
-g, --group-period=<seconds> | |
-p, --pass-options=<options> | |
EOF | |
exit 1 | |
fi | |
git -C "$FOLDER" log --format="%at" "$OTHER_OPT" | sort \ | |
| awk -v first="$FIRST_DELAY" -v threshold="$GROUP_TIME" ' | |
{ | |
diff = $0 - prev; | |
spent += (diff > threshold) ? first : diff; | |
prev = $0; | |
} | |
END { print spent / 3600 }' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment