2009-04-19

Chain scripts execution in git hooks

The common git hook is something like:
#!/bin/sh

exec "another script"
and since "exec" replace the current script with the other one, only one command can be execute in a hook. Even more, the common hook takes input from the standard input, so the first command takes it, and the second?

The real situation was reportbug post-receive hook, that looked like:
#!/bin/sh

exec /usr/local/bin/git-commit-notice
but I wanted to add seanius' tagpending hook to it. The solution I found was:
#!/bin/sh

# to save stdin on a file to pass to both scripts
cat > post-receive_tmpfile

/usr/local/bin/git-commit-notice < post-receive_tmpfile
/git/reportbug/reportbug.git/hooks/git-post-receive-url-notifications.py < post-receive_tmpfile

rm post-receive_tmpfile
that saves the stdin to a file, passed again to both the scripts.

Of course, I'd be happy to hear more elegant solutions :)

5 comments:

netfilter said...

TEXT=`cat`

echo "$TEXT" | command1
...
echo "$TEXT" | commandN

Josh said...

#!/bin/bash
tee >(command1) | command2

dato said...

/usr/bin/pee from the moreutils package:

#! /bin/sh

exec pee /usr/local/bin/git-commit-notice /git/reportbug/reportbug.git/hooks/git-post-receive-url-notifications.py

Sandro Tosi said...

Thanks for your comments :)

@netfilter: It's pretty much the same, but with different syntax; personally I prefer my version, but indeed it's another solution :)

@josh: your code only works for 2 commands to chain together, while there can several commands you want to execute in the same hook (and it's also a little bit "ugly" :) )

@dato: very cool tool, nice to know it exists. Sadly, it can only be useful if you have the capability to install executable on the git repository server.

mildred said...

I suppose you can always chain tee commands:

tee >(command1) | tee >(command2) | command3

And it seems that you can even do something like:

echo a | tee >(cat) >(cat) >(cat) | cat

(at least with zsh)