Search code examples
bashgitgithooks

Call a script from a git hook


Let's say I have two scripts in server /hooks folder:

First one initiates logging and writes essential information about push: (post-receive)

#!/bin/sh
read oldrev newrev refname
LOGFILE=post-receive.log
echo " push - Old SHA: $oldrev -> $newrev >> $LOGFILE
sh ./post-receive-logic >> $LOGFILE

Second one does actual deploying: (post-receive-logic)

#!/bin/sh
cd ~/proj
pm2 stop ~/proj/main.js
git --git-dir ~/proj/.git --work-tree ~/proj pull
npm install
pm2 restart ~/proj/main.js
echo "finished"

When I push a commit, second script never gets called: no changes in working tree, no server being killed and restarted, no output specific to second script.

If I call ./post-receive-logic by hand, everything goes fine, server stops, files being pulled, server starts again.

I tried call it without sh, like this:

./post-receive-logic >> $LOGFILE

but no luck.

What am I doing wrong?


Solution

  • Exercise: where is . (or $PWD) during the post-receive hook operation?

    When you run it, it's whatever your $PWD is. What about when it's run automatically? (Have a look in the receiving system's bare git repository: your $LOGFILE output will be in that directory.)

    (There's a missing close quote in the hook text in your posting, so presumably you hand-copied some part(s) of the script and perhaps there's something else missing. Also, be sure the hook has execute-permission. But my guess is that you're being bitten by the fact that git runs hooks with $PWD set to the .git directory, not the hook directory.)

    (Side note: your hook is probably incomplete, as it only reads one oldrev newrev refname, but a git push can push many refs. Normally you should loop: while read oldrev newrev refname; do ...; done. If you have a pre-receive hook that rejects pushes that push more than one ref, though, this particular post-receive hook could be correct.)