Skip to content

Instantly share code, notes, and snippets.

@bitinn
Last active February 2, 2024 12:35
Show Gist options
  • Star 4 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save bitinn/834756d57f3d47df97937aab68162ae6 to your computer and use it in GitHub Desktop.
Save bitinn/834756d57f3d47df97937aab68162ae6 to your computer and use it in GitHub Desktop.
pre-commit hook to prevent large file on git commit (and allow git-lfs tracked binary files to pass through)
#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments. The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".
# Redirect output to stderr.
exec 1>&2
FILE_SIZE_LIMIT_KB=1024
CURRENT_DIR="$(pwd)"
COLOR='\033[01;33m'
NOCOLOR='\033[0m'
HAS_ERROR=""
COUNTER=0
# generate file extension filter from gitattributes for git-lfs tracked files
filter=$(cat .gitattributes | grep filter=lfs | awk '{printf "-e .%s$ ", $1}')
# before git commit, check non git-lfs tracked files to limit size
files=$(git diff --cached --name-only | sort | uniq | grep -v $filter)
while read -r file; do
if [ "$file" = "" ]; then
continue
fi
file_path=$CURRENT_DIR/$file
file_size=$(ls -l "$file_path" | awk '{print $5}')
file_size_kb=$((file_size / 1024))
if [ "$file_size_kb" -ge "$FILE_SIZE_LIMIT_KB" ]; then
echo "${COLOR}${file}${NOCOLOR} has size ${file_size_kb}KB, over commit limit ${FILE_SIZE_LIMIT_KB}KB."
HAS_ERROR="YES"
((COUNTER++))
fi
done <<< "$files"
# exit with error if any non-lfs tracked files are over file size limit
if [ "$HAS_ERROR" != "" ]; then
echo "$COUNTER files are larger than permitted, please fix them before commit" >&2
exit 1
fi
exit 0
@dfroger
Copy link

dfroger commented Jun 5, 2022

on GNU/Linux, I switch to #!/bin/bash (because of the <<< at line 37), and to echo -e.

@Francois-JEAN
Copy link

Francois-JEAN commented Oct 21, 2022

If there is a space in username, there is a problem when retrieving the file size.
Line 30 can be replace by file_size=$(stat --printf="%s" "$file_path")

And to avoiding testing deleted file Line 24 can be replace by files=$(git diff --cached --name-only --diff-filter=d | sort | uniq | grep -v $filter)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment