Skip to content

Instantly share code, notes, and snippets.

@annarailton
Last active January 29, 2019 12:21
Show Gist options
  • Save annarailton/79ac9ffb2ec7acb2937cc7c12e45349e to your computer and use it in GitHub Desktop.
Save annarailton/79ac9ffb2ec7acb2937cc7c12e45349e to your computer and use it in GitHub Desktop.
Warns users if staged files are larger than some limit
#!/usr/bin/python3
"""
Checks file size of committed files. If there are stage files bigger than a
given size (`WARN_SIZE_MB`) then
* the commit is aborted
* you are told about the offending files
* you are told the command for forcing through the commit anyway
Save this file as "pre-commit" in your .git/hooks folder and do
$ chmod a+x pre-commit
You can change the file warning size limit by updating `WARN_SIZE_MB`.
"""
import os
import subprocess
import sys
# --------------------------------------
# Update to change the warning threshold
# --------------------------------------
WARN_SIZE_MB = 5
# --------------------------------------
# -----------------------------
# Do not change below this line
# -----------------------------
MAX_STR_LEN = 25
# Terminal colour codes
ENDC = '\033[0m'
BOLD = '\033[1m'
OKGREEN = '\033[92m'
WARNING = '\033[93m'
FAIL = '\033[91m'
def main():
git = subprocess.Popen(
['git', 'diff', '--cached', '--name-only', '--diff-filter=AM'],
stdout=subprocess.PIPE)
staged_files = git.stdout.read().decode("utf-8").strip().splitlines()
# Look at the size of all the staged files
big_files = []
ok_files = []
warn_size_bytes = WARN_SIZE_MB * 1000 * 1000
for file in staged_files:
size_in_bytes = os.path.getsize(file)
if len(file) > MAX_STR_LEN: # clean names for stdout
file = file[:MAX_STR_LEN - 3] + "..."
else:
file = file.ljust(MAX_STR_LEN)
if size_in_bytes >= warn_size_bytes:
big_files.append((file, size_in_bytes / 1000000))
else:
ok_files.append((file, size_in_bytes / 1000))
if big_files:
commit_aborted = FAIL + BOLD + ">" * 18 + " COMMIT ABORTED " + "<" * 18 + ENDC
print(commit_aborted)
print("The following files exceed the file size limit ({}MB):".format(
WARN_SIZE_MB))
for file, size in big_files:
print("\t" + file + FAIL + "\t{:0.2f}MB".format(size) + ENDC)
print("\nThe following files are OK:")
for file, size in ok_files:
print("\t" + file + OKGREEN + "\t{:0.2f}KB".format(size) + ENDC)
print(
"\nIf you still want to commit all these files please use the following command:"
)
print(WARNING + "\tgit commit --no-verify\n" + ENDC)
print(commit_aborted)
sys.exit(1)
sys.exit(0)
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment