git pre-commit hook to look for large files and commits

Platform Notice: Cloud Only - This article only applies to Atlassian products on the cloud platform.

Summary

Sometimes you need to check to make sure your developers do not create a large commit. Or put large files in a commit. This git pre-receive hook can accomplish this.

The steps outlined on this article are provided AS-IS. This means we've had reports of them working for some customers — under certain circumstances — yet are not officially supported, nor can we guarantee they'll work for your specific scenario.

You may follow through and validate them on your own non-prod environments prior to production or fall back to supported alternatives if they don't work out.

We also invite you to reach out to our Community for matters that fall beyond Atlassian's scope of support!

Environment

All git deployments that need to check if a file and/or a commit is larger than a default limit. If you want to have everyone using this repository to use this hook, please see Standardize git hooks across a repository for details on how to distribute the hook.

Solution

This pre commit hook makes sure no individual files and the commit are not over a size set by limits variables, commitlimit and filelimit. commitlimit sets the size of all staged files and are added together. filelimit checks each file for the size limit. This is set by setting limit to a reasonable value for a commit or file size. The default here is 10, making this script unusable.

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 #!/bin/sh commitlimit=$(git config hooks.filesizehardlimit) filelimit=$(git config hooks.filesizehardlimit) : ${commitlimit:=10} : ${filelimit:=10} list_new_or_modified_files() { # Only get the file name. Do not get deleted files. git diff --staged --name-only --diff-filter=ACMRTUXB } unmunge() { local result="${1#\"}" result="${result%\"}" env echo "$result" } check_file_size() { n=0 while read -r munged_filename do f="$(unmunge "$munged_filename")" h=$(git ls-files -s "$f"|cut -d' ' -f 2) s=$(git cat-file -s "$h") if [[ "$s" -gt $filelimit ]] then env echo 1>&2 "ERROR: size limit ($filelimit) exceeded: $munged_filename ($s)" n=$((n+1)) fi fs=$(($fs+$s)) done if [[ "$fs" -gt $limit ]] then env echo 1>&2 "ERROR: hard size limit ($commitlimit) bytes exceeded: $munged_filename ($fs)" fi [ $n -eq 0 ] } list_new_or_modified_files | check_file_size exit $n

There is a known issue if using submodules. You can see the error below. This is due to git diff in the script can include the hash from the submodules. This error can be ignored.

1 fatal: git cat-file: could not get object info

Here is the expected output of a commit failure:

1 2 3 4 5 $ git commit -m "Another attempt at commit large file" ERROR: size limit (10) exceeded: .githooks/pre-commit (746) ERROR: size limit (10) exceeded: bitbucket-pipelines.yml (3278) ERROR: hard size limit (10) bytes exceeded: (4024) $
Updated on April 15, 2025

Still need help?

The Atlassian Community is here for you.