使用GitPython,如何执行git submodule update --init

9 投票
2 回答
13129 浏览
提问于 2025-04-18 01:56

到目前为止,我的代码已经能正常工作,完成了以下任务。我想去掉subprocess.call()这一部分。

import git
from subprocess import call

repo = git.Repo(repo_path)
repo.remotes.origin.fetch(prune=True)
repo.head.reset(commit='origin/master', index=True, working_tree=True)

# I don't know how to do this using GitPython yet.
os.chdir(repo_path)
call(['git', 'submodule', 'update', '--init'])

2 个回答

-2

简短的回答是:你不能。

详细的回答是:你不能,而且这样做也没有意义。GitPython并不是对整个Git的完整实现。它只是提供了一些常用功能的高级接口。虽然有些操作是直接用Python实现的,但很多操作实际上是通过Git命令行接口来处理的。

比如,你的fetch这一行就是这样做的。实际上,它在背后使用了一些小技巧,让某些调用看起来像是用Python写的,虽然它们实际上是调用Git程序来处理结果——也使用了子进程。

所以,你可以尝试弄清楚如何使用GitPython提供的git命令接口来支持这些调用(你可以通过repo.git访问这个命令处理器的实例),或者你也可以继续直接使用“无聊”的子进程调用。

26

我的简短回答是:这样做方便又简单。

接下来是详细的回答。假设你有一个叫做 repo 的变量:

repo = git.Repo(repo_path)

然后,你只需要这样做:

for submodule in repo.submodules:
    submodule.update(init=True)

通过 submodule.module()(它的类型是 git.Repo),你可以像对待普通的代码库一样,对待你的子模块,进行所有操作,像这样:

sub_repo = submodule.module()
sub_repo.git.checkout('devel')
sub_repo.git.remote('maybeorigin').fetch()

我在自己的项目管理工具中使用这些东西,称之为 在 git 之上构建的工具


另外,如果你想更直接地做这件事,你可以不使用 call()subprocess,而是直接这样做:

repo = git.Repo(repo_path)
output = repo.git.submodule('update', '--init')
print(output)

你可以打印输出,因为这个方法返回的结果和你运行 git submodule update --init 时得到的输出是一样的(显然,print() 的部分 取决于 Python 的版本)。

撰写回答