Skip to content

Instantly share code, notes, and snippets.

@nanoant
Forked from iley/pre-receive
Last active December 10, 2015 19:35
Show Gist options
  • Save nanoant/139cb2b6f2fffa0c12ef to your computer and use it in GitHub Desktop.
Save nanoant/139cb2b6f2fffa0c12ef to your computer and use it in GitHub Desktop.
pre-receive hook to deny pushing big files
#!/usr/bin/perl -wl
use strict;
my $limit = 20 * 1024 * 1024;
my $hasBadFiles;
# human friendly sizes
sub hsize {
# http://www.perlmonks.org/?node_id=378580
(sort { length $a <=> length $b } map { sprintf '%.2g %s',
$_[0]/1024**$_->[1], $_->[0] }
["bytes"=>0], [KB=>1], [MB=>2], [GB=>3], [TB=>4], [PB=>5], [EB=>6])[0]
}
while (<>) {
chomp;
my ($old, $new, $ref) = split / /, $_;
my %visited = ();
my $log = ($old =~ /^0+$/ ? `/usr/bin/git log --pretty=%H $new`
: `/usr/bin/git log --pretty=%H $old..$new`);
for my $commit (split /\n/, $log) {
# pick new files in each commit
for my $entry (split /\n/,
($old =~ /^0+$/
? `/usr/bin/git diff-tree --no-commit-id -r $commit`
: `/usr/bin/git diff-tree --no-commit-id -r $old..$commit`)) {
if ($entry =~ /^:\d+ \d+ \w+ (\w+) \w+\t(.*)$/ && !$visited{$1}) {
my $sha = $1;
my $name = $2;
unless ($sha =~ /^0+$/) {
$visited{$sha} = 1;
# check file size
my $size = `/usr/bin/git cat-file -s $sha`;
chomp $size;
# reject file size is greater than limit
if ($size > $limit) {
my $shortsha = substr($commit, 0, 10);
my $hsize = hsize($size);
my $hlimit = hsize($limit);
print "'$name' of size $hsize in $shortsha is over $hlimit limit";
$hasBadFiles = 1;
}
}
}
}
}
}
$hasBadFiles and exit 1;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment