Git pre-/post-receive hooks not working. No push messages in journal.

Issue #578 resolved
Stefan Engel created an issue

I was wondering why no git push requests where showing up in my repository. Turns out, that the pre-/post-receive hooks are installed in the hooks directory, but fail to execute.

Some debugging showed that the problem seems to be the Python virtual environment used for running RhodeCode. The pre-/post-receive hooks get executed without the virtual environment, thus starting under the server wide Python installation where RhodeCode is not installed in.

When pushing to the server the pre-/post-receive hooks fail with an ImportError, because the "RhodeCode" module cannot be imported. This import error is silently dropped, the repository is updated and the updates show up in RhodeCode. But no 'push' message shows up in the journal.

The virtual environment is already set within ~/.bashrc, which works fine on login, but fails for git push. I even tried ~/.profile without success.

I don't know, why the virtual env is not available when git executes the hooks.

EDIT 20120926: ignore the next part and the attached helper script '', see next comment

To work around this problem for now, I temporaryly renamed the pre-/post-receive Python scripts into "pre-/post-receive.rhodecode" and created a script which checks whether or not the virtual environment is set. This script then sets the virtual environment and calls in turn the Python scripts. This works fine then, but has to be applied manually in each git repository.

I have attached this helper script including some information about the setup.

Comments (12)

  1. Marcin Kuzminski repo owner

    That is interesting, the hook line `/usr/bin/env python` should execute the virtualenv python. How do you run rhodecode via paster or mod_wsgi ? maybe it's just enought to set PYTHONPATH before starting rhodecode ? Also i'll read little more about if i made the subprocess call that executes git handler correctly pass in all env variables

  2. Stefan Engel reporter

    The solution is a little bit easier, no renaming of the Python hook scripts necessary.

    Instead convert them into Bash script with embedded Python. Thus these hook scripts can be easyly deployed from Rhodecode (just change the hook templates). See attached files.

    Currently for my setup I can live with just replacing the hook templates.

    Now only one issue remains: is there a way from within RhodeCode to configure which virtualenv should be used in the pre/post-receive scripts? I would like to revmove the hardcoded path to 'activate', even with an intermediate link to a well known place.

  3. Marcin Kuzminski repo owner

    I think i should set currently active python path when running subprocess calls that later execute the hooks, this way the hook always will use same python

  4. Stefan Engel reporter

    I added the following code to for testing (around line 225). I don't know if this is the right place, but this fix did the trick and the hooks are now working as expected whithout having to mess around with bash workarounds.

    import sys
            self.__inject_extras(repo_path, baseui, extras)
            # set python path to make git hooks happy ;-)
            os.environ['PYTHONPATH'] = ':'.join(sys.path)
                # invalidate cache on push
                if action == 'push':
  5. Stefan Engel reporter

    Seems to work. Now the hooks get executed and I see the 'push' entries in the journal. I think we can close this bug then.

    You can also tell that it works, because the hooks take a considerable amount of time to process. Here are some timings of a simple one line change of a file within a repo with only this file inside:

    Without hooks:

    $ time git push origin master
    Counting objects: 5, done.
    Writing objects: 100% (3/3), 233 bytes, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To http://localhost/rhodecode/testing/tst.git
       d95ca0a..8668e7e  master -> master
    real	0m0.829s
    user	0m0.012s
    sys	0m0.012s

    With hooks enabled:

    $ time git push origin master
    Counting objects: 5, done.
    Writing objects: 100% (3/3), 236 bytes, done.
    Total 3 (delta 0), reused 0 (delta 0)
    To http://localhost/rhodecode/testing/tst.git
       8668e7e..f559215  master -> master
    real	0m3.296s
    user	0m0.012s
    sys	0m0.004s

    That's nearly 2,5 seconds longer than with hooks.

  6. Marcin Kuzminski repo owner

    unfortunetly it's the overhead of running python, and the initializing whole pylons stack that is done there, but maybe i might spend some time trying to optimize that somehow

  7. Log in to comment