1

I'm new to git hooks. I'm not able to understand below pre-commit hook. Can anyone tell me how this works please.Here my doubt is how grep will be happened in committed files as we are not taking those files anywhere. Sorry if am asking wrong question but please help me in understanding git hooks..

#!/usr/bin/env ruby
if `grep -rls "require 'ruby-debug'; raise" *` != ""
  puts "You twit, you've left a debugger in!"
  exit(1)
end
  • This is a funny message, but why not write it in shell? It seems more natural to me to use grep in shell. – squiguy Nov 29 '13 at 04:59
  • Mine is ruby background I'm not flexible with shell scripts. Is there a way to learn basics of git hooks?. If so please help me. – user2986573 Nov 29 '13 at 05:02
  • The git hooks can be written in whatever language, the exit code is what is important. If you are comfortable searching files for text using Ruby, go ahead. You can `man githook` to read information from the manual about it. It is a great resource. The code is pretty straightforward Ruby. It reads "Unless the system calls grep result is empty, print a message and exit with exit code 1". – vgoff Nov 29 '13 at 05:24
  • @vgoff, So basically git searches in committed files context only am I ryt? – user2986573 Nov 29 '13 at 05:45
  • If I understand your comment correctly, you mean grep? No, grep will search your file structure, it is not aware of git. But you can get the listing of files that are git knows about by doing `git ls-files`. – vgoff Nov 29 '13 at 06:06
  • @vgoff Yes, you r right..am speaking about grep. How can i fetch only added or staged files and search in them? can u modify my script and give a small example if you don’t mind. So that i can get clear picture.Thanks for your patience – user2986573 Nov 29 '13 at 06:37

1 Answers1

4

You should rather grep on indexed (cached) files, instead of your working tree.
Otherwise, your grep could find debug instructions in files (or part of files) which aren't part of the next commit.

See "Git pre-commit hook : changed/added files":

git diff --cached --name-only --diff-filter=ACM

As explained in "Why You Need a Git Pre-Commit Hook and Why Most Are Wrong":

Most test against whatever files are currently on disk, not what is in the staging area (the files actually being committed).

The approach if that hook is a bit different: it stashes every work in progress before searching the files.

def main(all_files):
    # Stash any changes to the working tree that are not going to be committed
    subprocess.call(['git', 'stash', '-u', '--keep-index'], stdout=subprocess.PIPE)
Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250