如何在Python Git钩子中使用raw_input()?

16 投票
2 回答
2468 浏览
提问于 2025-04-17 02:24

我正在为Git写一个预提交钩子,这个钩子会运行pyflakes,并检查修改过的文件中是否有制表符和多余的空格(GitHub上的代码)。我想让这个钩子能够通过用户确认来覆盖,这样做的方式如下:

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)

这段代码会产生一个错误:

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

在Git钩子中使用raw_input()或类似的函数是可能的吗?如果可以的话,我哪里做错了?

2 个回答

-1

在命令行中,你可以这样做:

read ANSWER < /dev/tty
21

你可以使用:

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

git commit 会调用 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

在这个 Linux 系统上查看 /proc/21802/fd,可以看到进程 ID 为 21802 的文件描述符状态(也就是 pre-commit 这个进程):

  /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

所以,pre-commit 是在 sys.stdin 指向 /dev/null 的情况下启动的。 sys.stdin = open('/dev/tty') 这行代码把 sys.stdin 重定向到一个可以读取的文件,这样 raw_input 就能从中获取输入。

撰写回答