Is there a git hook that can prevent binary checks

Does anyone know of a good git hook that checks for binary files on commit and throws an error? I try to prevent the use of binaries in my repository, but sometimes people make mistakes.

Thanks!

+6
source share
3 answers

I don't know the existing hook, but git already has a hook that checks for the presence of "non-ascii names" as a pre-commit pattern. This will probably already be in existing git repositories like .git/hooks/pre-commit.sample .

Using this hook as a template and considering the answers to How to determine if a git file processes a file as binary or text? , you can do something like this (see "git semi-secret empty tree" , where EMPTY_TREE comes EMPTY_TREE ):

 #! /bin/sh stop_binaries=$(git config --get hooks.stop_binaries) exec 1>&2 if [ "$stop_binaries" = true ]; then EMPTY_TREE=$(git hash-object -t tree /dev/null) # or: EMPTY_TREE=4b825dc642cb6eb9a060e54bf8d69288fbee4904 if git diff --cached --numstat $EMPTY_TREE | grep -e '^-' >/dev/null; then echo Error: commit would add binary files: git diff --cached --numstat $EMPTY_TREE | grep -e '^-' | cut -f3- exit 1 fi fi 

This uses git diff --cached to see what would be done by comparing it all with the original empty tree. Note that it will reject commits with already existing (but unchanged) binaries; so that it rejects only new or changed binaries, add the against= logic from the non-ascii name hook. To reject only new binaries, also add the argument --diff-filter=A

Come up with this with additional error message text if you want. You can cancel the test (instead of saying “stop binaries”, make it stop by default, and you must set “allowbinaries” to add binary files), etc. And, of course, you can allow specific directories full of binaries, or something else by doing extra filtering on the output of the diff index.

+6
source

A shameless plugin, but I wrote a pre-receive hook that makes it much smarter and customizable after searching and searching for anything that worked out of the box with Git stock without installing a larger Git management system.

+2
source

We had a similar requirement for our git repo. We did not want to allow randomly registering very large or binary files, as they can inflate repos and are difficult to remove from history. Honestly, I am surprised that such a hook is not a requirement for all Git users. We wanted our client to be on the client side, so that the user immediately realized that he had made a mistake. We also wanted to allow the user to redefine the hook if they were sure that the file should be committed.

For checking binary files I just used Perls -B check. I decided to use the pre-commit hook. To override the hook, we simply print a reminder to tell the user to re-run the commit using -no-verify.

The maximum file size is arbitrary and set in the script. You can customize it to suit your situation.

You will also notice that this only checks for files that are being added (not modified) because we did not want the hook to become a nuisance every time a large or binary file is modified. If you want to be more strict, you can change the diff filter to use ACM (added, copied or modified).

 #!/usr/bin/perl # The hook should exit with non-zero status after issuing an appropriate # message if it wants to stop the commit. use strict; use warnings; my $file; my $MAX_SIZE = 100000; # Limit files to 100KB # Only check binary and file size when files are added otherwise users # get an error every time they modify they file. This has the dissadvantage # of not catching if a file grows too large after the initial commit # # Get list of added files only (ie new files) my @new_file_list = `git diff --cached --name-only --diff-filter=A`; foreach $file (@new_file_list) { chomp($file); # Check if file is binary if (-B $file) { print STDERR "WARNING: $file is binary.\n"; print STDERR "Please check with repo owner before committing binary files.\n"; print STDERR "To bypass this warning re-run your commit with the '--no-verify' option\n"; exit 1; } # Check if file is very large if (-s $file > $MAX_SIZE) { print STDERR "WARNING: $file is greater than $MAX_SIZE bytes.\n"; print STDERR "Please check with repo owner before committing very large files.\n"; print STDERR "To bypass this warning re-run your commit with the '--no-verify' option\n"; exit 1; } } 
0
source

Source: https://habr.com/ru/post/958880/


All Articles