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

107 投票
7 回答
153152 浏览
提问于 2025-04-17 18:31

我想用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 个回答

36

使用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")
64

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 这些库。

180

你有没有想过用GitPython呢?这个工具就是为了帮你处理这些麻烦事儿的。

import git  # pip install gitpython


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

要安装这个模块,你可以使用 pip install GitPython

这个项目可以在这里找到,GitPython

撰写回答