Created
November 18, 2020 04:29
-
-
Save zambonin/1a852d79aa4c9399a513583bca88561c to your computer and use it in GitHub Desktop.
File size vs time as given by a Git repository. Inspired by http://phdcomics.com/comics/archive.php?comicid=1915.
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 bash | |
# shellcheck disable=SC2214 | |
# | |
# A shell script that shows the size of a file in each commit that modifies it, | |
# alongside the timestamp taken from the author of the commit. This is useful | |
# to visualize the size evolution of a file. | |
# | |
# It accepts a single option to customize its behavior, described as | |
# follows. The last argument must be a valid file tracked by its respective | |
# repository, with the first file obtained from git-ls-files(1) as default. | |
# | |
# -C, --directory=<path> | |
# Pass the path of the desired directory to Git tools. | |
# | |
# For instance, to visualize the size breakdown of file "bar" inside directory | |
# "foo" in a graph, one can use the command below. | |
# | |
# $ bash git-size-history.sh -C foo bar \ | |
# | gnuplot -e 'set term dumb; set xdata time; set timefmt "%s"; | |
# plot "-" using 1:2 with lines notitle' | |
# | |
# Parsing of long options is adapted from https://stackoverflow.com/a/28466267. | |
DIR_PATH="." | |
while getopts C:-: OPT ; do | |
if [ "$OPT" = "-" ] ; then | |
OPT="${OPTARG%%=*}" | |
OPTARG="${OPTARG#$OPT}" | |
OPTARG="${OPTARG#=}" | |
fi | |
case "$OPT" in | |
C | directory ) DIR_PATH="${OPTARG:-$DIR_PATH}" ;; | |
??* ) exit 1 ;; | |
\? ) exit 2 ;; | |
esac | |
done | |
shift $((OPTIND-1)) | |
FILE_PATH="${1:-$(git -C "$DIR_PATH" ls-files | head -1)}" | |
if ! git -C "$DIR_PATH" ls-files --error-unmatch "$FILE_PATH" >/dev/null ; then | |
cat <<-EOF | |
Usage: sh ${0##*/} [options] [file] | |
-C, --directory=<path> | |
EOF | |
exit 1 | |
fi | |
paste \ | |
<(git -C "$DIR_PATH" rev-list --all "$FILE_PATH" \ | |
| sed -e "s/$/:$FILE_PATH/g" \ | |
| git -C "$DIR_PATH" cat-file --batch-check) \ | |
<(git -C "$DIR_PATH" --no-pager log --format="%at" "$FILE_PATH") \ | |
| awk '{print $(NF), $(NF - 1) }' |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment