如何从 Python 中调用“git pull”?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/15315573/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I call 'git pull' from within Python?
提问by djq
Using the github webhooks, I would like to be able to pull any changes to a remote development server. At the moment, when in the appropriate directory, git pullgets any changes that need to be made. However, I can't figure out how to call that function from within Python. I have tried the following:
使用 github webhooks,我希望能够将任何更改拉到远程开发服务器。目前,当在适当的目录中时,git pull获取需要进行的任何更改。但是,我不知道如何从 Python 中调用该函数。我尝试了以下方法:
import subprocess
process = subprocess.Popen("git pull", stdout=subprocess.PIPE)
output = process.communicate()[0]
But this results in the following error
但这会导致以下错误
Traceback (most recent call last): File "", line 1, in File "/usr/lib/python2.7/subprocess.py", line 679, in initerrread, errwrite) File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory
回溯(最近一次调用):文件“”,第 1 行,在文件“/usr/lib/python2.7/subprocess.py”中,第 679 行,在 initerrread, errwrite 中)文件“/usr/lib/python2. 7/subprocess.py", line 1249, in _execute_child raise child_exception OSError: [Errno 2] No such file or directory
Is there a way that I can call this bash command from within Python?
有没有办法可以从 Python 中调用这个 bash 命令?
采纳答案by jleahy
Have you considered using GitPython? It's designed to handle all this nonsense for you.
你考虑过使用 GitPython 吗?它旨在为您处理所有这些废话。
import git
g = git.cmd.Git(git_dir)
g.pull()
回答by phihag
subprocess.Popenexpects a list of the program name and arguments. You're passing it a single string, which is (with the default shell=False) equivalent to:
subprocess.Popen需要程序名称和参数的列表。你传递给它一个字符串,它(默认shell=False)相当于:
['git pull']
That means that subprocess tries to find a program named literally git pull, and fails to do so: In Python 3.3, your code raises the exception FileNotFoundError: [Errno 2] No such file or directory: 'git pull'. Instead, pass in a list, like this:
这意味着子进程试图找到一个名为字面意思的程序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]
By the way, in Python 2.7+, you can simplify this code with the check_outputconvenience function:
顺便说一句,在 Python 2.7+ 中,您可以使用check_output便利功能简化此代码:
import subprocess
output = subprocess.check_output(["git", "pull"])
Also, to use git functionality, it's by no way necessary (albeit simple and portable) to call the git binary. Consider using git-pythonor Dulwich.
此外,要使用 git 功能,调用 git 二进制文件绝不是必要的(尽管简单且可移植)。考虑使用git-python或Dulwich。
回答by orip
Try:
尝试:
subprocess.Popen("git pull", stdout=subprocess.PIPE, shell=True)
回答by Tuxdude
This is a sample recipe, I've been using in one of my projects. Agreed that there are multiple ways to do this though. :)
这是一个示例配方,我一直在我的一个项目中使用。同意有多种方法可以做到这一点。:)
>>> 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
The problem with your code was, you were not passing an array for subprocess.Popen()and hence was trying to run a single binary called git pull. Instead it needs to execute the binary gitwith the first argument being pulland so on.
你的代码的问题是,你没有传递一个数组subprocess.Popen(),因此试图运行一个名为git pull. 相反,它需要git使用第一个参数执行二进制文件pull,依此类推。
回答by Eric
The accepted answer using GitPythonis little better than just using subprocessdirectly.
使用GitPython的公认答案比直接使用好一点subprocess。
The problem with this approach is that if you want to parse the output, you end up looking at the result of a "porcelain" command, which is a bad idea
这种方法的问题在于,如果您想解析输出,您最终会查看“瓷器”命令的结果,这是一个坏主意
Using GitPython in this way is like getting a shiny new toolbox, and then using it for the pile of screws that hold it together instead of the tools inside. Here's how the API was designed to be used:
以这种方式使用 GitPython 就像得到一个闪亮的新工具箱,然后将它用于将它固定在一起的一堆螺丝而不是里面的工具。以下是 API 的设计使用方式:
import git
repo = git.Repo('Path/to/repo')
repo.remotes.origin.pull()
If you want to check if something changed, you can use
如果你想检查是否有变化,你可以使用
current = repo.head.commit
repo.remotes.origin.pull()
if current != repo.head.commit:
print("It changed")
回答by davidvandebunte
If you're using Python 3.5+ prefer subprocess.runto subprocess.Popenfor scenarios it can handle. For example:
如果你正在使用Python 3.5+喜欢subprocess.run到subprocess.Popen了场景,它可以处理。例如:
import subprocess
subprocess.run(["git", "pull"], check=True, stdout=subprocess.PIPE).stdout

