我试图说服我的同事,使用子进程来获取repo头是不好的,因为生成一个子进程或创建一个进程有很多开销。为了说服他,我创建了两个脚本,并对它们进行了剖析,但结果并不是我所期望的(python-git会比subprocess快)。
这是第一个脚本 - test_git_module.py
我介绍过的
import git
def test():
repo = git.Repo(".", search_parent_directories=True)
test()
在用cProfile--剖析后 python3 -m cProfile test_git_module -s
,我得到的输出是 78059 function calls (75806 primitive calls) in 0.130 seconds
另一方面当我对剧本进行剖析时 test_subprocess.py
输出是 6529 function calls (6430 primitive calls) in 0.017 seconds
test_subprocess.py
import subprocess
import os
import sys
def test():
SELF_DIRPATH = os.path.dirname(__file__)
WORKSPACE_DIRPATH = (
subprocess.run(["git", "rev-parse", "--show-toplevel"], stdout=subprocess.PIPE, check=True)
.stdout.decode(sys.stdout.encoding)
.strip()
)
test()
所以,很明显,在这种情况下,python-git根本帮不上忙,而且对于做这种任务来说,它的速度真的很慢。这就给我带来了一个问题,那就是什么时候以及为什么要使用Python-GIT而不是子进程?
git
模块不是为了执行速度而创建的。调用shell命令并解析输出,会让你的代码变得不可读,难以维护,而且有时会很棘手。调用python函数而不是 subprocess.run
最常见的是更优雅、可读、方便。
git rev-parse --show-toplevel
是一个简单的输出解析。那么 git log
? 我不是说做不到,但你95%的代码都是关于调用shell和解析输出,而不是你的逻辑。很明显,你可以为你需要的每个命令创建一个函数,但这就是 git
模块已经是。
这就像ORM与裸SQL查询一样。大多数开发人员更喜欢ORM,因为方便。
使用 subprocess
具有明显的优势。
subprocess
模块是标准库的一部分。至于解析输出,有了 git log
塑造容易解析的输出并不难。
git log --pretty=format:"%h%x09%an%x09%ad%x09%s"
(从 本回答)这将使每一个提交都以单行形式产生,字段以 标签 角色。很容易 来转换。
import subprocess as sp
args = ['git', 'log', '--pretty=format:%h%x09%an%x09%ad%x09%s']
commits = [ln.split('\t') for ln in sp.check_output(args, text=True).splitlines()]
当然还有其他的程序,处理输出比较困难。但是。