17

https://github.com/typicode/husky has the ability to run git hooks automatically in a way that they can be shared between teams in the repository it self.

How can this even work? Since the hooks need to be in .git/hooks which is not added to repository.

Does it wraps git command and intercept commands, running hooks when they happen?

I want to reproduce this behavior for python and php projects without the need to depend on npm or node.

Apollo
  • 1,296
  • 2
  • 11
  • 24
geckos
  • 5,687
  • 1
  • 41
  • 53
  • Have you looked at the source code? I'm not a javascript expert, but it looks to me that husky installs the hooks when you install it. – Roland Smith Jul 31 '19 at 20:18
  • I was trying that. At https://github.com/typicode/husky/blob/f955c07cd75a4dd44dd0ec053add07d8e57b8ca6/src/installer/index.ts – geckos Jul 31 '19 at 21:44
  • It seems to copy the hooks at `createHook` at above link. This seems to happen at `npm install` time instead of `git clone`. I would need something like this in a pip package or composer package if I want this to run on python or php project – geckos Jul 31 '19 at 21:49

2 Answers2

16

As of version 5 husky uses git's core.hooksPath git config core.hooksPath .husky to be exact. This is done in husky install step.

Since .husky folder created by husky install contains pre-commit script, it will be run before commit. By default it will have npm test in it but you can edit it to your wish.

You can do something similar in any project. Just add .githooks folder and hook files inside it(check .git/hooks for sample files). But you have to run git config core.hooksPath .githooks while cloning the repo(or setting up hooks for the first time). You can have some init script to do that.
npm has scripts.prepare which can run commands on npm install which is husky install in this case.

succerror
  • 341
  • 3
  • 4
6

While the husky dependency is installed (through npm install, npm add husky, yarn install, ...) git hooks are created/updated in the .git/hooks directory. If the hook is triggered through a git command a script from husky is triggered that will execute a command based on the package manager you used for the installation. If you use npm npx --no-install husky-run $hookName "$gitParams" is executed. That command looks into your configuration and executes the command defined for the hook there.

It's like a proxy for git hooks. The proxy is installed once and executed every time by a normal git hook. If it is executed it looks into the configuration and executes the commands defined there.

Nico
  • 185
  • 2
  • 7
  • Thanks for your answer. This is something interesting, installing stuff run arbitrary code, which is a potencial security risk. I asked because I tried to reproduce this behavior with pure git, but it is impossible. At last I can't find a way to get hooks copied to .git/hooks at clone, so I put they on readme and let the user install it manually. Thanks again – geckos May 14 '20 at 17:40
  • @geckos: yes, there is a definite security risk. But then again: checking out and building *any* software is a potential security risk because almost all build system allow executing arbitrary external commands (i.e. arbitrary code execution). So you shouldn't be building untrusted software anyway. – Joachim Sauer Oct 15 '21 at 13:07