How can I run a virtualenv python script as a git pre-commit hook

This is my pre-commit script:

#!/bin/bash
for f in .git/hooks/pre-commit.d/*; do
    if [ -x "$f" ]; then
        if ! "$f"; then
            echo "DID NOT COMMIT YOUR CHANGES!";
            exit 1
        fi
    fi
done

One of the executables in pre-commit.d is a python script (pre-commit-pylint.py) that starts with:

#!/usr/bin/env python
import pylint

pylint is installed on my virtualenv. My problem is that git runs pre-commit prepending /usr/libexec/git-core:/usr/bin to $PATH, so even if my virtualenv is activated the pre-commit.d/pre-commit-pylint.py script runs with the system /usr/bin/python (instead of running with the virtualenv python).

I want to have hooks that are compatible for developers that are not using virtualenv. Is there any way to run my python script with virtualenv transparently (ie, staying compatible with developers that are using their system python)?

  • Which PIP Returns Global Instead of VirtualEnv
  • Should I commit /bin directory when working with virtualenv?
  • Corrupt pack file on git aws.push
  • Pip install from a specific commit prompts “requirements already satisfied”
  • Using git to manage virtualenv state: will this cause problems?
  • Why shouldn't I push a virtualenv to Heroku?
  • Having trouble setting up dev server for Django and website
  • Virtual env: Connection in use error
  • 2 Solutions collect form web for “How can I run a virtualenv python script as a git pre-commit hook”

    You can check in your pre-commit script for the $VIRTUAL_ENV variable and prepend it to $PATH accordingly:

    #!/bin/bash
    
    if [ -n $VIRTUAL_ENV ]; then
        PATH=$VIRTUAL_ENV/bin:$PATH
    fi
    
    for f in .git/hooks/pre-commit.d/*; do
        if [ -x "$f" ]; then
            if ! "$f"; then
                echo "DID NOT COMMIT YOUR CHANGES!";
                exit 1
            fi
        fi
    done
    

    What I ended up doing is: the .git file structure:

    • .git/hooks/pre-commit
    • .git/hooks/pre-commit-main.py

    .git/hooks/pre-commit:

    #!/usr/bin/env bash
    export PATH="$THE_GOOD_PATH"
    python "$GIT_DIR/hooks/pre-commit-main.py"
    

    .git/hooks/pre-commit-main.py:

    #!/usr/bin/env python
    import sys
    print sys.version_info
    

    Then, when you call git commit, make sure that THE_GOOD_PATH, is defined:

    export THE_GOOD_PATH="$PATH"
    git commit
    

    You could also export THE_GOOD_PATH="$PATH" from your .profile or the toplevel of your application and symlink all hooks to a single file.

    This method has the advantage of being virtualenv agnostic: it also works with Ruby RVM rbenv.

    I wrote to the Git developers at: http://permalink.gmane.org/gmane.comp.version-control.git/258454 asking them to leave our PATH alone, but the initial reply was WONTFIX.

    Git Baby is a git and github fan, let's start git clone.