通过git钩子执行python子进程

通过git钩子执行python子进程,python,git,subprocess,pipe,Python,Git,Subprocess,Pipe,我在Git存储库上运行Gitolite,我在那里用Python编写了post接收钩子。我需要在git存储库目录下执行“git”命令。有几行代码: proc = subprocess.Popen(['git', 'log', '-n1'], cwd='/home/git/repos/testing.git' stdout=subprocess.PIPE, stderr=subprocess.PIPE) proc.communicate() 在我进行新的提交并推送到存储库之后,脚本将执行并显示 f

我在Git存储库上运行Gitolite,我在那里用Python编写了post接收钩子。我需要在git存储库目录下执行“git”命令。有几行代码:

proc = subprocess.Popen(['git', 'log', '-n1'], cwd='/home/git/repos/testing.git' stdout=subprocess.PIPE, stderr=subprocess.PIPE)
proc.communicate()
在我进行新的提交并推送到存储库之后,脚本将执行并显示

fatal: Not a git repository: '.'
如果我跑

proc = subprocess.Popen(['pwd'], cwd='/home/git/repos/testing.git' stdout=subprocess.PIPE, stderr=subprocess.PIPE)
正如预期的那样,它指出了git存储库的正确路径(/home/git/repos/testing.git)


如果我从bash手动运行这个脚本,它将正常工作并显示“git log”的正确输出。我做错了什么?

cwd参数后缺少一个逗号:

proc = subprocess.Popen(['git', 'log', '-n1'], cwd='/home/git/repos/testing.git', stdout=subprocess.PIPE, stderr=subprocess.PIPE)

cwd参数后缺少逗号:

proc = subprocess.Popen(['git', 'log', '-n1'], cwd='/home/git/repos/testing.git', stdout=subprocess.PIPE, stderr=subprocess.PIPE)

您可以尝试使用命令行开关设置git存储库:

proc = subprocess.Popen(['git', '--git-dir', '/home/git/repos/testing.git', 'log', '-n1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
--git dir
需要指向实际的git目录(工作树中的
.git
)。请注意,对于某些命令,还需要设置
--工作树
选项

另一种设置目录的方法是使用
GIT\u DIR
环境变量:

import os
env = os.environ.copy()
env['GIT_DIR'] = '/home/git/repos/testing.git'
proc = subprocess.Popen((['git', 'log', '-n1', stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
显然,hooks已经设置了
GIT_DIR
,但这显然不适合您的情况(可能是相对的);上面的代码将其设置为完整的显式路径

编辑:显然,它只在指定cwd和重写
GIT_DIR
var:

import os
repo = '/home/git/repos/testing.git'
env = os.environ.copy()
env['GIT_DIR'] = repo
proc = subprocess.Popen((['git', 'log', '-n1', stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, cwd=repo)

您可以尝试使用命令行开关设置git存储库:

proc = subprocess.Popen(['git', '--git-dir', '/home/git/repos/testing.git', 'log', '-n1'], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
--git dir
需要指向实际的git目录(工作树中的
.git
)。请注意,对于某些命令,还需要设置
--工作树
选项

另一种设置目录的方法是使用
GIT\u DIR
环境变量:

import os
env = os.environ.copy()
env['GIT_DIR'] = '/home/git/repos/testing.git'
proc = subprocess.Popen((['git', 'log', '-n1', stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env)
显然,hooks已经设置了
GIT_DIR
,但这显然不适合您的情况(可能是相对的);上面的代码将其设置为完整的显式路径

编辑:显然,它只在指定cwd和重写
GIT_DIR
var:

import os
repo = '/home/git/repos/testing.git'
env = os.environ.copy()
env['GIT_DIR'] = repo
proc = subprocess.Popen((['git', 'log', '-n1', stdout=subprocess.PIPE, stderr=subprocess.PIPE, env=env, cwd=repo)

这很难做到;这将产生一个语法错误,而不是用户看到的错误。在SO上发布时,通常会出现转录错误。这很难做到;这将产生一个语法错误,而不是用户看到的错误。在SO上发布时,可能会出现一个转换脚本错误。钩子在运行时已经设置了环境变量
$GIT_DIR
,因此如果要将GIT指向其他目录,则必须覆盖它。请注意,通常钩子也是使用
GIT_DIR=.
运行的(即,它是相对的,这让我感到惊讶)。最好是完全清除它,或者将它设置为您想要的。@torek:有趣的是,这可能是OP的错误之处。更新了答案,因为
env.update(os.environ)
会删除我们试图设置的自定义
GIT\u DIR
var。哦,哈哈,我没有仔细阅读你答案的第二部分,没有意识到你是在用那种方式使用
.update
。不管怎样,是的,我怀疑这才是OP的真正问题。(实验告诉我,
--git dir
覆盖了
$git_dir
,所以你的第一个答案应该有用。)非常感谢,我甚至没想到这里会有任何环境变量。现在,它只适用于重新定义的'GIT_DIR'变量和Popen方法中指定的'cwd'选项。请将它添加到您的答案中。非常感谢。我一直在尝试一些解决方案,但您的(在编辑部分)是我见过的最好和最简单的。钩子是使用环境变量
$GIT_DIR
运行的,因此如果您想将GIT指向不同的目录,您必须覆盖它。请注意,通常钩子也是使用
GIT_DIR=.
运行的(即,它是相对的,这让我感到惊讶)。最好是完全清除它,或者将它设置为您想要的。@torek:有趣的是,这可能是OP的错误之处。更新了答案,因为
env.update(os.environ)
会删除我们试图设置的自定义
GIT\u DIR
var。哦,哈哈,我没有仔细阅读你答案的第二部分,没有意识到你是在用那种方式使用
.update
。不管怎样,是的,我怀疑这才是OP的真正问题。(实验告诉我,
--git dir
覆盖了
$git_dir
,所以你的第一个答案应该有用。)非常感谢,我甚至没想到这里会有任何环境变量。现在,它只适用于重新定义的'GIT_DIR'变量和Popen方法中指定的'cwd'选项。请将它添加到您的答案中。非常感谢。我一直在尝试一些解决方案,但你的(在编辑部分)是我见过的最好和最简单的。