Although described as a Bash script, this appears to be a portable shell script that can be run by any POSIX-conformant shell. That's a good thing, as it means we can use a much smaller, leaner shell such as Dash.
If you haven't yet installed
shellcheck, I recommend you do so (there's also a web version you can try). It highlights the following:
Piping the file into
wc isn't an efficient way to measure size of a file; we could simply use
bytez=$(stat -c %s "$(git rev-parse --show-toplevel)/$1")
And instead of running
git rev-parse for every file in the changeset, run it once and remember the value in a variable.
The error message should go to the standard error stream (I see the whole script is redirected to
It's not obvious why
set -e is right down inside the
if - I'd normally put that immediately after the shebang.
set -u to help detect a likely cause of errors.
Spelling: unless you really mean "1 millibit", that should be "1MB".
A suggestion that might fall into the "too cute" category: since
git config --bool always produces
false as output, we can simply execute that as a command:
if ! $(git config --bool hooks.allowbigfiles)
Line-based reading (i.e.
git diff --name-only | while read) isn't totally robust; there's a
-z option provided to produce NUL-separated output. This will require Bash, though, in order to
if [ "$(stat -c %s "$toplevel/$1")" -gt 1000000 ] ; then
Error: Attempting to commit a file larger than approximately 1MB.
Commiting large files slows jenkins builds, clones, and other
operations we would rather not slow down.
Consider generating, downloading, zipping, etc these files.
Offending file - $1
# If you want to allow large files to be committed set this variable to true.
allowbigfiles=$(git config --bool hooks.allowbigfiles)
# Redirect output to stderr.
if ! "$allowbigfiles"
toplevel=$(git rev-parse --show-toplevel)
git diff --name-only -z --cached "$1" |
while IFS= read -d '' -r x; do too_big "$x"; done