78

Is there a way to track git hook changes? I have three hooks that only show up on my machine, not when my other developers fetch. Trying to git add doesn't work.

Josh Lee
  • 171,072
  • 38
  • 269
  • 275
Hans
  • 3,403
  • 3
  • 28
  • 33
  • I'd love the answer to this too! I can't push a description to my webserver. I've seen suggestions to use a symlink in the controlled directory, pointing to the file under .git, but I couldn't get it to work – Robert Dec 16 '10 at 02:48
  • possible duplicate of [Can Git hook scripts be managed along with the repository?](http://stackoverflow.com/questions/427207/can-git-hook-scripts-be-managed-along-with-the-repository) – Cascabel Dec 16 '10 at 03:00
  • I voted to close with the oldest exact duplicate. Here are two more: http://stackoverflow.com/questions/2050450/git-hooks-management and http://stackoverflow.com/questions/3462955/putting-git-hooks-into-repository/3464399#3464399 The general suggestion is to symlink the hooks, either the whole directory, or one-by-one in a fancier way as I suggested in the second of those two links. – Cascabel Dec 16 '10 at 03:01
  • I've done the symlink way but for initial clones there is a setup that needs to be done first. Not the end of the world, but seems like it would be a nice feature. – Hans Dec 16 '10 at 03:37
  • 2
    That's why you put a script to take care of it inside the repository, so it's just a single step after cloning. – Cascabel Dec 16 '10 at 03:51
  • A point that IMO should be clarified relative to the above discussion; That a manual step is needed after cloning before the hooks will be enabled is BY DESIGN. Automatically setting up arbitrary code to run merely as a result of cloning would be a huge security risk. – Mark Adelsberger Oct 22 '19 at 20:23

6 Answers6

55

http://benjamin-meyer.blogspot.com/2008/10/git-hooks.html

Files in the .git/hooks directory are not part of the repository and so they are not tracked. A workaround is to have a git_hooks directory at the top of your repository like done in Arora and symlink .git/hooks to git_hooks whenever you clone. This way the hooks will be part of the project, under revision control and accessible to everyone.

Brian Clapper
  • 25,705
  • 7
  • 65
  • 65
  • EDIT : Files in the .git/* directory are not part of the repository and so they are not tracked. – Jaseem May 14 '12 at 18:37
  • 3
    +1 great tip - just gotta remember to symlink, but seeing the git_hooks directory should be a good reminder... – kfmfe04 Nov 16 '12 at 16:18
  • @kfmfe04 you don't need to remember anything :) just use [build script](https://en.wikipedia.org/wiki/Build_automation) – sobi3ch Apr 03 '15 at 13:03
26

I realise this question is years old, but I feel this needs to be said for travellers like myself who wind up here: Hooks are not tracked by design! Brian's answer will work, but the deal with that is that you are effectively trusting everyone else you are working with to not put malicious code in the repository, which your hooks then execute without question; this is the very definition of a security hole.

Philip Adler
  • 2,111
  • 17
  • 25
  • 3
    Good point! But this could be solved by putting this `git_hooks` directory in totally separate project and give permission to repo only to people that have enough knowledge and they are responsible for changes. – sobi3ch Apr 03 '15 at 13:01
  • 3
    I run `rake spec` all the time and trust that I don't work with some psychopath that has put `system("rm -rf / --no-preserve-root")` in the Rakefile. I don't see how trusting my collaborators to have not committed malicious code to the git hooks is any different... – lamont Aug 19 '16 at 07:44
  • @lamont sometimes the code is malicious but the programmer is not. If you feel you can trust the people you work with to that extent, then great, but that doesn't change that the hooks are not tracked by design and for this reason. – Philip Adler Aug 19 '16 at 14:56
  • 12
    i understand that code checked into the repository can be malicious. I've run unit tests which have run `FileUtils.rm_rf(".")` on my repo and wiped out my local tree completely (and could have easily nuked my home directory). My argument is that git-hooks are no more privileged than any of the other thousands and thousands of lines of code in the repo that I run on a daily basis. All of it has the ability to ruin my day. Can you explain the fundamental difference between git hooks and my unit testing framework and tests? – lamont Aug 24 '16 at 01:01
  • Actually, they are "more privileged" in the sense that the hooks run automatically in some cases before you would have been able to examine them as part of the process of pulling the code- unlike any other component you mention. – Philip Adler Sep 27 '16 at 17:30
  • @PhilipAdler: The hooks will not be executed if you don't execute any other action than pulling the code from the repository. Moreover, the @BrianClapper solution needs you to copy or link the `git_hooks` directory. Before doing that, you MUST check its content. There is nothing out of control while doing that way. – Damien Flament Jun 15 '17 at 17:40
  • @DamienFlament I am given to understand that is true only for the first clone. Code can be changed after that fact and provided the directory is not deleted then you are not forced to re-inspect the code. The first part of your comment is true... but then why have the hooks at all if you are only pulling? – Philip Adler Jun 18 '17 at 15:23
  • 2
    @PhilipAdler: I don't say you should only pull the code ! I just pointed out that "pull-only" operations will not fire the git hooks. So you are free to check the content of the hooks without any risk before copy them. But it's true the hooks can be modified afterward. So linking them seems dangerous. But copying is not risky while you check them before. – Damien Flament Jun 18 '17 at 22:02
  • Yes, that's fine. – Philip Adler Jul 06 '17 at 21:53
  • *I've run unit tests which have run FileUtils.rm_rf(".") on my repo* -- lol wut?? This actually made me laugh out loud---there's got to be a good story or a really bad colleague or both there... – modulus0 Nov 14 '22 at 01:00
9

Reviving this old thread, you could have a separate version controlled directory which contains your hooks then use the git config core.hooksPath to target that directory.

Maj. Dave
  • 93
  • 1
  • 2
  • 4
    then how do you make sure anyone in the team do this configure before commit code? – TangHongWan Apr 10 '19 at 13:00
  • 2
    @PageNotFound you put the instructions in the README of the project and also add the linting step to a stage in your pipeline, in case someone forgets they'll be reminded when the build fails. Not ideal, but works fine in practice. – emerino May 01 '20 at 20:31
3

Modifying Brian's answer to take into account Philip's important point:

If you have any user with write access that creates a hook (say, post-commit) with '#!/bin/sh rm -rf ~' there goes your home directory. (Or maybe something more benign but still stupid.)

To protect against this, it would be best not to symlink the directory, but copy them manually to and from a git_hooks directory. Yes, you have to remember to manually copy theses files when you update them, but better than nothing, and still you don't give someone user-level access to commands on your machine.

UPDATE: As mentioned below, if you plan on changing your hooks a bunch, you could make a wrapper script which copies the files and then runs the commit. However automating a commit (with git add and inputting an automated message) is really messy. A better idea would be to have one of your hooks do the copy to this 'git_hooks' directory, before the commit. This way malicious user wouldn't be able to commit a file that will run on the next hook call.

jpmorris
  • 882
  • 2
  • 10
  • 22
  • you don't need to remember anything :) just use [build script](https://en.wikipedia.org/wiki/Build_automation). Then you can symlink or copy or whatever else if you have different idea. – sobi3ch Apr 03 '15 at 13:07
2

Use template dirs. From a git clone, you can us the flag --template=<template_directory> to add files to the $GIT_DIR. You will also need to create a dir that holds your template or use gits provided location /usr/share/git-core/templates. By using a template dir you can have an active hook ready to run in the hooks dir from creation.

I'm not sure how often your people will be making edits, but you could save this template in a repo that all have access to. Really this should be one hook that runs a file in the repo that contains all of the code you need to automatically run.

Like others have mentioned, as soon as you're executing unknown code automatically you open yourself up to risk.

Ace
  • 306
  • 2
  • 11
2

Another solution (which is not related to tracking / versioning) could be the usage of a plugin that will handle hooks for you.

For example: In the case of a web app, imagine that you can add one script in package json that will configure pre commit hooks !

Here is a good example: https://github.com/typicode/husky

In the end, this script can be under version control and you don't have to deal with hooks folder inside .git

G. Frx
  • 2,350
  • 3
  • 19
  • 31