pre-receive-block-large-files 2.98 KB
Newer Older
Hamilton, Steven P's avatar
Hamilton, Steven P committed
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
#!/bin/bash

##########################################################################################
# This script was taken from a stackoverflow:
#
#    http://stackoverflow.com/questions/7147699/limiting-file-size-in-git-repository
#
# It would seem that all software posed on StackOverflow by default
# has a Creative Common license:
#
#   http://creativecommons.org/licenses/by-sa/2.5/
#
# That license says:
# You are free to:
#
#    Share — copy and redistribute the material in any medium or format
#    Adapt — remix, transform, and build upon the material
#    for any purpose, even commercially.
#
#    The licensor cannot revoke these freedoms as long as you follow the license terms.
#
##########################################################################################

# 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.
#
# This is called for a generic driver script pre-receive that passes
# in a single update ref as:
#
#    <oldrev> <newrev> <ref>
#
# as commandline arguments.
#

# Reference to incoming SHA1 is found in $2 (not the ref being updated)
newrev=$2
#echo "newrev=$newrev"

# 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 (or set the default to 49M so that we
# will not cause a warning with github)
filesizelimitmb=$(git config hooks.filesizelimitmb)
if [ -z "$filesizelimitmb" ]; then
  filesizelimitmb=49
fi
#echo "filesizelimitmb=$filesizelimitmb"

filesizelimit=$(expr $filesizelimitmb \* 1024 \* 1024)
#echo "filesizelimit=$filesizelimit"

# 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=$(git ls-tree --full-tree -r -l $newrev \
  | sort -k 4 -n -r | head -1 \
  | sed 's/^ *//;s/ *$//;s/\s\{1,\}/ /g' )
#echo "biggest_checkin_normalized:\n$biggest_checkin_normalized\n"

# Based on that, we can find what we are interested about
filesize=`echo $biggest_checkin_normalized | cut -d ' ' -f4,4`
#echo "filesize=$filesize"

# 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: Trying to push file that is larger than allowed filesizelimitmb=${filesizelimitmb}M" >&2
  echo  >&2
  echo "File size limit is $filesizelimit, and you tried to push file named $filename of size $filesize." >&2
  echo  >&2
  echo "Contact the repository administrators for details (see repo attribute config hooks.filesizelimitmb)!" >&2
  exit 1
fi

exit 0