Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is it possible to use raw_input() in a Python Git hook?

I am writing a pre-commit hook for Git that runs pyflakes and checks for tabs and trailing spaces in the modified files (code on Github). I would like to make it possible to override the hook by asking for user confirmation as follows:

answer = raw_input('Commit anyway? [N/y] ')
if answer.strip()[0].lower() == 'y':
    print >> sys.stderr, 'Committing anyway.'
    sys.exit(0)
else:
    print >> sys.stderr, 'Commit aborted.'
    sys.exit(1)

This code produces an error:

Commit anyway? [N/y] Traceback (most recent call last):
  File ".git/hooks/pre-commit", line 59, in ?
    main()
  File ".git/hooks/pre-commit", line 20, in main
    answer = raw_input('Commit anyway? [N/y] ')
EOFError: EOF when reading a line

Is it even possible to use raw_input() or a similar function in Git hooks and if yes, what am I doing wrong?

like image 903
badzil Avatar asked Sep 15 '11 20:09

badzil


People also ask

What is Python Raw_input?

Python raw_input function is used to get the values from the user. We call this function to tell the program to stop and wait for the user to input the values. It is a built-in function. The input function is used only in Python 2. x version.

Can I write a Git hook in Python?

Git hooks are language agnostic. I wrote this small hook as a shell script, but you can use other languages liek Perl, Ruby or Python. Here is an example of a pre-commit hook in written in Python.

How do you write raw input in Python?

The raw_input() function reads a line from input (i.e. the user) and returns a string by stripping a trailing newline. This page shows some common and useful raw_input() examples for new users. Please note that raw_input() was renamed to input() in Python version 3.

How does Git hook work?

Git hooks are scripts that run automatically every time a particular event occurs in a Git repository. They let you customize Git's internal behavior and trigger customizable actions at key points in the development life cycle.


1 Answers

You could use:

sys.stdin = open('/dev/tty')
answer = raw_input('Commit anyway? [N/y] ')
if answer.strip().lower().startswith('y'):
    ...

git commit calls python .git/hooks/pre-commit:

% ps axu
...
unutbu   21801  0.0  0.1   6348  1520 pts/1    S+   17:44   0:00 git commit -am line 5a
unutbu   21802  0.1  0.2   5708  2944 pts/1    S+   17:44   0:00 python .git/hooks/pre-commit

Looking inside /proc/21802/fd (on this linux box) shows the state of the file descriptors for the process with PID 21802 (the pre-commit process):

  /proc/21802/fd:
  lrwx------ 1 unutbu unutbu 64 2011-09-15 17:45 0 -> /dev/null
  lrwx------ 1 unutbu unutbu 64 2011-09-15 17:45 1 -> /dev/pts/1
  lrwx------ 1 unutbu unutbu 64 2011-09-15 17:45 2 -> /dev/pts/1
  lr-x------ 1 unutbu unutbu 64 2011-09-15 17:45 3 -> /dev/tty
  lr-x------ 1 unutbu unutbu 64 2011-09-15 17:45 5 -> /dev/null

Thus, pre-commit was spawned with sys.stdin pointing at /dev/null. sys.stdin = open('/dev/tty') redirects sys.stdin to an open filehandle from which raw_input can read.

like image 108
unutbu Avatar answered Oct 15 '22 18:10

unutbu