Alex
Alex

Reputation: 646

Why does my post-receive hook hang while reading from a subprocess pipe?

I'm running Gitolite over the Git repository and I have post-receive hook there. The script of this hook written in Python and fails after

proc = subprocess.Popen('git log', shell = True, stdout=subprocess.PIPE)
out = proc.stdout.read()

It doesn't execute after these lines. If I run this script manually, it works perfect.

What I'm doing wrong?

Upvotes: 1

Views: 414

Answers (2)

KurzedMetal
KurzedMetal

Reputation: 12946

From subprocess documentation:

Warning

Use communicate() rather than .stdin.write, .stdout.read or .stderr.read to avoid deadlocks due to any of the other OS pipe buffers filling up and blocking the child process.

I'd avoid using shell=True if possible too (IMO it's only useful if you wanna use shell built-ins and it's platform/shell specific), and pass Popen command as a list, like ['git', 'log']

Try something like:

>>> proc = subprocess.Popen(['git', 'log'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
>>> proc.communicate()
('', 'fatal: Not a git repository (or any of the parent directories): .git\n')

communicate()[0] is stdout, communicate()[1] is stderr.

Upvotes: 1

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84413

Your pipe is probably not returning. If that is the case, you can:

  1. Run git with the --no-pager flag to prevent your PAGER or GIT_PAGER from hanging the process.

  2. Limit your log output with the -n flag to keep piped output to a reasonable size. The subprocess library clearly says:

    [T]he child process may block if it generates enough output to a pipe to fill up the OS pipe buffer.

Upvotes: 0

Related Questions