如何在Python中调用'git pull'?
我想用GitHub的webhooks功能,把任何更改拉取到远程开发服务器上。目前,在合适的目录下,使用git pull
可以获取需要更新的更改。但是,我不知道怎么在Python里面调用这个功能。我试过以下代码:
import subprocess
process = subprocess.Popen("git pull", stdout=subprocess.PIPE)
output = process.communicate()[0]
但是这导致了以下错误:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/subprocess.py", line 679, in __init__
errread, errwrite)
File "/usr/lib/python2.7/subprocess.py", line 1249, in _execute_child
raise child_exception
OSError: [Errno 2] No such file or directory
有没有办法让我在Python里面调用这个bash命令呢?
7 个回答
使用GitPython的这个答案,其实比直接用subprocess
稍微好一点。
不过,这种方法有个问题,就是如果你想分析输出结果,你最终得到的只是一个“表面命令”的结果,这其实不是个好主意。
用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")
subprocess.Popen
这个函数需要你传入一个列表,里面包含程序的名称和参数。而你现在传入的是一个字符串,这样做(默认情况下 shell=False
)就相当于:
['git pull']
这意味着,subprocess 会试图找到一个名为 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-python 或者 Dulwich 这些库。
你有没有想过用GitPython呢?这个工具就是为了帮你处理这些麻烦事儿的。
import git # pip install gitpython
g = git.cmd.Git(git_dir)
g.pull()
要安装这个模块,你可以使用 pip install GitPython
这个项目可以在这里找到,GitPython