Skip to content

Instantly share code, notes, and snippets.

@stroucki
Created October 12, 2016 00:08
Show Gist options
  • Save stroucki/a90cb68990311ef6e8860b85a52ad07c to your computer and use it in GitHub Desktop.
Save stroucki/a90cb68990311ef6e8860b85a52ad07c to your computer and use it in GitHub Desktop.
Limit size of files pushed to a repository
#!/bin/bash
# Script to limit the size of a push to git repository.
# Git repo has issues with big pushes, and we shouldn't have a real need for those
#
# eis/02.02.2012
# adapted by stroucki 20161011 to guard against large files the user has deleted, but are part of history
# --- Safety check, should not be run from command line
if [ -z "$GIT_DIR" ]; then
echo "Don't run this script from the command line." >&2
echo " (if you want, you could supply GIT_DIR then run" >&2
echo " $0 <ref> <oldrev> <newrev>)" >&2
exit 1
fi
# Test that tab replacement works, issue in some Solaris envs at least
testvariable=`echo -e "\t" | sed 's/\s//'`
if [ "$testvariable" != "" ]; then
echo "Environment check failed - please contact git hosting." >&2
exit 1
fi
# File size limit is meant to be configured through 'hooks.filesizelimit' setting
filesizelimit=$(git config hooks.filesizelimit)
# If we haven't configured a file size limit, use default value of about 10M
if [ -z "$filesizelimit" ]; then
filesizelimit=10000000
fi
# Reference to incoming checkin can be found at $3
#refname=$3
while read oldrev newrev refname ; do
REVLIST=""
if expr "$oldrev" : '0*$' >/dev/null ; then
REVLIST=`git rev-list "$newrev"`
else
REVLIST=`git rev-list "$newrev" "^$oldrev"`
fi
# With this command, we can find information about the file coming in that has biggest size
# We also normalize the line for excess whitespace
biggest_checkin_normalized=$(for foo in $REVLIST;do git ls-tree --full-tree -r -l $foo;done|sort -u | sort -k 4 -n -r | head -1 | sed 's/^ *//;s/ *$//;s/\s\{1,\}/ /g')
# Based on that, we can find what we are interested about
filesize=`echo $biggest_checkin_normalized | cut -d ' ' -f4,4`
# Actual comparison
# To cancel a push, we exit with status code 1
# It is also a good idea to print out some info about the cause of rejection
if [ $filesize -gt $filesizelimit ]; then
# To be more user-friendly, we also look up the name of the offending file
filename=`echo $biggest_checkin_normalized | cut -d ' ' -f5,5`
echo "Error: Too large push attempted." >&2
echo >&2
echo "File size limit is $filesizelimit, and you tried to push file named $filename of size $filesize." >&2
#echo "Contact configuration team if you really need to do this." >&2
exit 1
fi
done # while read
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment