Here is my precommit hook (found on stack overflow) :
#!/bin/bash
# taken from : https://stackoverflow.com/questions/39576257/how-to-limit-file-size-on-commit
hard_limit=$(git config hooks.filesizehardlimit)
soft_limit=$(git config hooks.filesizesoftlimit)
: ${hard_limit:=1000000}
: ${soft_limit:=500000}
status=0
bytesToHuman() {
b=${1:-0}; d=''; s=0; S=({,K,M,G,T,P,E,Z,Y}B)
while ((b > 1000)); do
d="$(printf ".%01d" $((b % 1000 * 10 / 1000)))"
b=$((b / 1000))
let s++
done
echo "$b$d${S[$s]}"
}
# Iterate over the zero-delimited list of staged files.
while IFS= read -r -d '' file ; do
hash=$(git ls-files -s "$file" | cut -d ' ' -f 2)
size=$(git cat-file -s "$hash")
#hash=0
#size=0
if (( $size > $hard_limit )); then
echo "Error: Cannot commit '$file' because it is $(bytesToHuman $size), which exceeds the hard size limit of $(bytesToHuman $hard_limit)."
status=1
elif (( $size > $soft_limit )); then
echo "Warning: '$file' is $(bytesToHuman $size), which exceeds the soft size limit of $(bytesToHuman $soft_limit). Please double check that you intended to commit this file."
fi
done < <(git diff -z --staged --name-only --diff-filter=d)
exit $status
It works great but now my commit are very slow.
Without the hook or if I comment "hash" (git ls-files command) and "size" (git cat-file command) variables the execution time of the commit is 3 seconds. Using the complete script, it takes 300 seconds.
I have 1000 files in the commit. Do you know if this is normal to have such a latency when using this hook? My computer is quite recent (Intel(R) Core(TM) i7-10700 CPU @ 2.90GHz 2.90 GHz, 32Go ram) and I don't have performance problems elsewhere.
gittag.git diff --rawand extract the hash from there, pass the list of hashes togit cat-file --batch-check="%(objectname) %(objectsize)"to find the object sizes. Filter the large ones. So far there's no loop needed. Then from there it is a bit more tedious to work back to the file name, but you will have to do that only when there is an error to report, not during the normal operation.git diff-index -z --cached --diff-filter=d @ | awk '{id=$4;getline;print id,$0}' RS='\0' | git cat-file --batch-check='%(objectsize) %(rest)'will do fine in the absence of actual newlines in your paths.