Question

I'm trying to write a post-commit hook, I have a Git repository on a mapped drive (V:), msysgit installed in C:\Git, and Python in C:\Python26.

I'm running TortoiseGit on Windows 7 64 Bit.

The script is:

#!C:/Python26/python

import sys
from subprocess import Popen, PIPE, call

GIT_PATH = 'C:\Git\bin\git.exe'
BRANCHES = ['master']
TRAC_ENV = 'C:\TRAC_ENV'
REPO_NAME = 'core'

def call_git(command, args):
    return Popen([GIT_PATH, command] + args, stdout=PIPE).communicate()[0]

def handle_ref(old, new, ref):
    # If something else than the master branch (or whatever is contained by the
    # constant BRANCHES) was pushed, skip this ref.
    if not ref.startswith('refs/heads/') or ref[11:] not in BRANCHES:
        return

    # Get the list of hashs for commits in the changeset.
    args = (old == '0' * 40) and [new] or [new, '^' + old]
    pending_commits = call_git('rev-list', args).splitlines()[::-1]

    call(["trac-admin", TRAC_ENV, "changeset", "added", REPO_NAME] + pending_commits)

if __name__ == '__main__':
    for line in sys.stdin:
        handle_ref(*line.split())

If I run the "git commit..." command from command line, it doesn't seem to even run the hook script at all.

Was it helpful?

Solution

According to the githooks man page,

[The post-commit hook] is invoked by git-commit. It takes no parameter, and is invoked after a commit is made.

It takes no parameters. In Python, that means sys.argv[1:] will be an empty list. The man page doesn't say what, if anything, is sent to stdin, but presumably nothing. Let's check that.

I made a little git directory and put this in .git/hooks/post-commit:

#!/usr/bin/env python 
import sys
def handle_ref(old, new, ref):
    with open('/tmp/out','w') as f:
        f.write(old,new,ref)
if __name__ == '__main__':
    with open('/tmp/out','w') as f:
        f.write('post-commit running')
    for line in sys.stdin:
        handle_ref(*line.split())
        with open('/tmp/out','w') as f:
            f.write('Got here')

and made it executable.

When I make a commit I see the /tmp/out file has been created, but its only contents are

post-commit running

So the script ran, but the for line in sys.stdin: loop does nothing since nothing is sent to sys.stdin.

You're going to need to generate the arguments to send to handle_ref in some other way, perhaps through a subprocess call to some git command.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top