multiple commands are not working in git post-receive
Asked Answered
M

4

6

I'm using git with trac. After push I want two thing to be done:

  1. Sending email to development team with diff
  2. If there is some special phrase in commit message (like "see #1"), then I want the commit message to be placed in trac ticket.

The first thing is solved by git-commit-notifier. It works perfectly after I have created post-receive hook:

#!/bin/sh

/var/lib/gems/1.8/bin/git-commit-notifier /etc/git-commit-notifier.yml

My second requirement can be solved as discribed at http://trac-hacks.org/wiki/GitPlugin#post-receivehookscripts. It also works perfectly with such post-receive hook:

#!/bin/sh

/var/trac/testgit/commit-updater

Both 2 things works when they are separate. But I need to combine them. So I have created post-receive hook:

#!/bin/sh

/var/trac/testgit/commit-updater
/var/lib/gems/1.8/bin/git-commit-notifier /etc/git-commit-notifier.yml

It is very funny, but this is not working. The commands run perfectly well when the run separately, but only first one works when they are placed into post-receive hook.

If I have such hook:

#!/bin/sh

/var/trac/testgit/commit-updater
/var/lib/gems/1.8/bin/git-commit-notifier /etc/git-commit-notifier.yml

I do receive the following error

/var/lib/gems/1.8/gems/git-commit-notifier-0.8.0/bin/git-commit-notifier:12: undefined method `strip' for nil:NilClass (NoMethodError)
        from /var/lib/gems/1.8/bin/git-commit-notifier:19:in `load'
        from /var/lib/gems/1.8/bin/git-commit-notifier:19

But if I change to order of this 2 commands I do not receive any errors, but only the first command works.

I will appreciate any help. I'm trying to solve this problem for a long time and I have no ideas.

Monopetalous answered 10/8, 2010 at 11:19 Comment(3)
@bessarabov: looks like its trying to read from STDIN, but can't, presumably because the first line is reading everything.Recti
If ngoozeff is right, have your hook copy its stdout to a temp file, and then redirect that temp file into each of the two commands.Yabber
@Recti thank you! your suggestion is 100% correct. =) With the help of @Yabber everything is working now!Monopetalous
R
5

Assuming my comment is correct, and commit-updater is eating all of stdin, this should do the trick:

#!/bin/sh

FILE=`mktemp`
cat - > $FILE
cat $FILE | /var/trac/testgit/commit-updater
cat $FILE | /var/lib/gems/1.8/bin/git-commit-notifier /etc/git-commit-notifier.yml
rm $FILE
Recti answered 10/8, 2010 at 12:28 Comment(3)
Thank you! The only thing that I had to change in your script is to remove quotes: FILE=mktemp And after that it works perfectly =)Monopetalous
the backticks are needed, otherwise you get "mktemp" as file name.Whet
Works great, thanks. I however that the backticks ARE required as @Whet says.Theomachy
C
1

I found ngoozeff's solution useful, but I had to make a few additions. At first, the script should fail if one of the hook fails. At second, some hooks may expect arguments. In my case the gitzilla hook was like that.

For me the following worked for combining gitzilla and gitolite hooks:

#!/bin/sh

FILE=`mktemp`
cat - > $FILE
cat $FILE | $GIT_DIR/hooks/update.gitzilla $* || exit 1 
cat $FILE | $GIT_DIR/hooks/update.gitolite $* || exit 1
rm $FILE

Note the $* and the exit statements. You can also use the $GIT_DIR variable. The update.gitzilla and update.gitolite files are symbolic links.

Catamite answered 11/9, 2011 at 11:11 Comment(0)
B
1

An alternative to using a file would be:

#!/bin/sh

while read oldrev newrev refname
do
   echo $oldrev $newrev $refname | /var/trac/testgit/commit-updater
   echo $oldrev $newrev $refname | /var/lib/gems/1.8/bin/git-commit-notifier /etc/git-commit-notifier.yml
done

Source: http://mmm.beachtemple.com/blog/2009/04/06/git-post-receive-hook/

Bonnie answered 16/1, 2014 at 10:10 Comment(1)
This would not work well with mailing, e.g. calling /usr/share/git-core/contrib/hooks/post-receive-email, because a new process is created for each input line, so it could create as many e-mails.Boyce
T
0

Since the input data is not all that huge, you can go without temporary file and keep the data in the shell:

#!/bin/sh

refs=$(cat)
/var/trac/testgit/commit-updater <<END
$refs
END
/var/lib/gems/1.8/bin/git-commit-notifier /etc/git-commit-notifier.yml <<END
$refs
END
Thamos answered 19/3, 2014 at 20:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.