通过git钩子执行python子进程
我在Git存储库上运行Gitolite,我在那里用Python编写了post接收钩子。我需要在git存储库目录下执行“git”命令。有几行代码:通过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
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'选项。请将它添加到您的答案中。非常感谢。我一直在尝试一些解决方案,但你的(在编辑部分)是我见过的最好和最简单的。