Skip to content

Instantly share code, notes, and snippets.

@PasaOpasen
Last active October 1, 2023 08:33
Show Gist options
  • Save PasaOpasen/25348d27e7c7019f613644295b19ada2 to your computer and use it in GitHub Desktop.
Save PasaOpasen/25348d27e7c7019f613644295b19ada2 to your computer and use it in GitHub Desktop.
git precommit hook which adds big staged files to LFS
#!/bin/sh
#
# moves big staged files to LFS if not already tracked
#
# the file is tracked as LFS if it is mentioned in .gitattributes
#
#
FILE_SIZE_LIMIT_MB=10
CURRENT_DIR="$(pwd)"
staged_files="$(git diff --cached --name-only | sort | uniq)"
non_staged_files="$(git status --porcelain | grep -v -E '^A\s' | cut -c 1-3 --complement)"
non_staged_files="$(echo "${non_staged_files}" | grep -v "${staged_files}")"
#
# find already tracked files
#
attr=.gitattributes
if [ ! -f $attr ]
then
echo "create empty $attr"
touch $attr
git add -f $attr
fi
already_lfs="$(cut -f1 -d' ' .gitattributes)"
attr_status="$(echo "${non_staged_files}" | grep -E $attr)"
echo "=====> Staged files to commit:"
echo "${staged_files}"
echo
echo "${staged_files}" | while read -r file
do
if [ ! -f "$file" ]
then
continue
fi
file_path=$CURRENT_DIR/$file
file_size=$(ls -l "$file_path" | awk '{print $5}')
file_size_mb=$((file_size / 1024 / 1024))
if [ ${file_size_mb} -ge ${FILE_SIZE_LIMIT_MB} ] # must be lfs
then
echo -n "=====> Potentially LFS file ${file} (${file_size_mb} MB): "
if [ -n "${attr_status}" ]
then
echo -e "ERR\n\tmust be tracked as LFS, but .gitattibutes has unstaged changes"
exit 1
fi
if [ -n "$(echo "${already_lfs}" | grep -E "^$file$")" ]
then
echo "OK"
else
if [ -n "$(echo "${non_staged_files}" | grep -E "^$file$")" ]
then
echo -e "ERR\n\tnot tracked as LFS and has unstaged changes"
exit 1
else
echo "moving to LFS..."
git restore --staged "${file}"
git lfs track "${file}"
git add -f "$attr" "${file}"
echo -e "\tOK"
fi
fi
fi
done
echo "SUCCESSFUL CHECK"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment