Last Updated: May 15, 2019
·
4.224K
· bartlomiejdanek

Git hooks - how don't push nasty code?

Probably everyone pushed some code to remote branch which shouldn't be pushed. I mean such things like:

  • binding.pry
  • throw
  • exit
  • console.log
  • and other cool stuff ;)

To prevent this situation, I've created a git hook for pre-commit script.
It checks code, if current changes include keyword, you won't be able to create a commit. Example

# user.rb
class User
  def initialize
    binding.pry
  end

  def create
    throw :create
  end
end

When you call git commit you get:

# Check following lines:
#   user.rb contains binding.pry at line 4. 
#   user.rb contains throw at line 8.

If you want to use it, you have to copy pre-commit file from this repo to your .git/hooks for given repository.

You can also copy it to template directory, for instance /usr/local/Cellar/git/1.8.2/share/git-core/templates/hooks/ or define your own template directory like here.

If you see, that something is wrong, you can report an issue on Github or send me a pull request or just leave a comment.

9 Responses
Add your response

As I see, you use grep command. As this hook work on Git-only repositories why not use git grep --cached? It will work faster and you won't need to run git diff-index --name-only HEAD --.

Also I will move keywords to Git config. Then you can add this as template and for every project you can have another keywords that you don't want to see in public repo.

over 1 year ago ·

@hauleth thanks for feedback, however git grep --cached doesn't show changes which aren't committed. It searches only in blobs registered in the index file.

Btw. feedback applied :)

over 1 year ago ·

@bartlomiejdanek but why bother about untracked/unindexed files? Maybe I still workin on them and I want commit only that files. Then your hook will unable me to do sa if I don't disable hooks for this commit. IMHO that much better idea to check only indexed and commited files, not all.

over 1 year ago ·

@hauleth I think that you don't understand how it works ;).
It doesn't check all files, it checks only changed/added files, just call git diff-index --name-only HEAD -- in one of your repositories where you have some uncommitted changes. Create file, run script again, add file to commit and run it again.

over 1 year ago ·

@bartlomiejdanek I understand what you mean but my point is that sometimes I work on bunch of files and I wanna commit only part of them. Then your hook will unable me to do that if in some of them I still have, i.e. a binding.pry. In my way it stop you if and only if you have that in code that you are trying to commit.

over 1 year ago ·

Ok, now I see your point. Will try to improve the hook a bit.

over 1 year ago ·

@hauleth you can always bypass the commit hooks with the '--no-verify' flag. That way if you are writing a cross browser console.log class and it needs to be there you can still check it in.

over 1 year ago ·

@brombomb --no-verify argument doesn't work for hooks (what I know..).
@hauleth - I rewrote this hook into Ruby with --no-verify support.

over 1 year ago ·

Nice script Bartlomiej, we're using a slight variation @ OnePageCRM - http://developer.onepagecrm.com/blog/2015/02/11/git-precommit.html

over 1 year ago ·