如何在Python中调用'git pull'?

时间:2013-03-09 20:30:32

标签: python git bash github

使用github webhooks,我希望能够将任何更改提取到远程开发服务器。目前,当在适当的目录中时,git pull会获得需要进行的任何更改。但是,我无法弄清楚如何从Python中调用该函数。我尝试过以下方法:

import subprocess
process = subprocess.Popen("git pull", stdout=subprocess.PIPE)
output = process.communicate()[0]

但是这会导致以下错误

  

Traceback(最近一次调用最后一次):文件“”,第1行,in      文件“/usr/lib/python2.7/subprocess.py”,第679行,in   的初始化       errread,errwrite)文件“/usr/lib/python2.7/subprocess.py”,第1249行,在_execute_child中       raise child_exception OSError:[Errno 2]没有这样的文件或目录

有没有办法可以在Python中调用这个bash命令?

6 个答案:

答案 0 :(得分:111)

你考虑过使用GitPython吗?它旨在为您处理所有这些废话。

import git 

g = git.cmd.Git(git_dir)
g.pull()

https://github.com/gitpython-developers/GitPython

答案 1 :(得分:35)

subprocess.Popen需要一个程序名称和参数列表。你传给它一个字符串,它是(默认的shell=False)相当于:

['git pull']

这意味着子进程尝试查找名为字面git pull的程序,但未能这样做:在Python 3.3中,您的代码引发异常FileNotFoundError: [Errno 2] No such file or directory: 'git pull'。相反,传入一个列表,如下所示:

import subprocess
process = subprocess.Popen(["git", "pull"], stdout=subprocess.PIPE)
output = process.communicate()[0]

顺便说一下,在Python 2.7+中,您可以使用check_output便利功能简化此代码:

import subprocess
output = subprocess.check_output(["git", "pull"])

此外,要使用git功能,调用git二进制文件绝对不需要(尽管简单和可移植)。请考虑使用git-pythonDulwich

答案 2 :(得分:2)

这是一个示例配方,我一直在我的一个项目中使用。同意有多种方法可以做到这一点。 :)

>>> import subprocess, shlex
>>> git_cmd = 'git status'
>>> kwargs = {}
>>> kwargs['stdout'] = subprocess.PIPE
>>> kwargs['stderr'] = subprocess.PIPE
>>> proc = subprocess.Popen(shlex.split(git_cmd), **kwargs)
>>> (stdout_str, stderr_str) = proc.communicate()
>>> return_code = proc.wait()

>>> print return_code
0

>>> print stdout_str
# On branch dev
# Untracked files:
#   (use "git add <file>..." to include in what will be committed)
#
#   file1
#   file2
nothing added to commit but untracked files present (use "git add" to track)

>>> print stderr_str

您的代码存在的问题是,您没有为subprocess.Popen()传递数组,因此尝试运行名为git pull的单个二进制文件。相反,它需要执行二进制git,第一个参数为pull,依此类推。

答案 3 :(得分:2)

使用GitPython接受的答案比直接使用subprocess更好。

这种方法的问题在于,如果您想解析输出,最终将看到“瓷器”命令which is a bad idea

的结果。

以这种方式使用GitPython就像获得一个闪亮的新工具箱,然后将其用作将其固定在一起而不是内部工具的一堆螺丝钉。 API的设计使用方式如下:

import git
repo = git.Repo('Path/to/repo')
repo.remotes.origin.pull()

如果要检查是否有所更改,可以使用

current = repo.head.commit
repo.remotes.origin.pull()
if current != repo.head.commit:
    print("It changed")

答案 4 :(得分:2)

如果您使用的是Python 3.5+,则可以使用subprocess.run而不是subprocess.Popen。例如:

import subprocess
subprocess.run(["git", "pull"], check=True, stdout=subprocess.PIPE).stdout

答案 5 :(得分:-3)

尝试:

subprocess.Popen("git pull", stdout=subprocess.PIPE, shell=True)