Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent pushes to git containing tabs in certain files (e.g. *.cpp, *.h, CMakeLists.txt)

Tags:

I'd like my remote repository to refuse any pushes that contains a file that contains a tab, but only if the file belongs in a certain class (based on the filename). Is that possible?
I have looked a bit at the update hook in githooks, and I think that is the correct one.

So in short, a push should be rejected if:

  1. there is a file of the listed types (*.cpp, *.h, CMakeLists.txt)
  2. that contains one or more tab characters.
like image 779
Esben Mose Hansen Avatar asked Oct 21 '10 08:10

Esben Mose Hansen


2 Answers

Uh oh, this question seems to have slipped through the cracks. Hope you're still out there, Esben!

You're looking for an update hook, which is run once for each ref updated. The arguments are the name of the ref, the old object name (commit SHA1), and the new object name.

So, all you really need to do is check the diff between the old and new and make sure it meets your standards. This isn't totally straightforward, of course, but it's totally manageable. Here's what I'd do:

Save the following script to .git/hooks/update.

old=$2
new=$3

# that's a literal tab, because (ba)sh turns \t into t, not a tab
# make sure your editor doesn't expand it to spaces
git diff --name-only $old $new | egrep '(\.(cpp|h)$)|^CMakeLists.txt$' | xargs -d'\n' git diff -U0 $old $new -- | grep -q '^+.* ' && exit 1

That lists all the files which differ between the old and new, greps for all the desired ones, gets the diff for them (with zero lines of context, since we don't care), and greps for an added line (starting with +) containing a tab. The grep exits success if it finds one, which will let the && run exit 1, causing the hook to exit failure and abort the update!

Note that this is slightly different from your requirements - it checks if the diff adds any tab characters. This is probably better in the long run; once you've made sure your existing code's okay, it's the same thing, except much faster since it doesn't have to search all the content.

like image 53
Cascabel Avatar answered Sep 20 '22 03:09

Cascabel


You could setup a pre-push hook, but this is not really in the spirit of the git publication mechanism.

I would rather go with:

  • a pre-commit hook, preventing any commit with the wrong content
  • or a filter driver that you can easily associate with the right types of file, and which can fix or report any improper content.
like image 23
VonC Avatar answered Sep 21 '22 03:09

VonC