adr*_*nos 16 git performance download git-clone git-submodules
克隆具有大量子模块的git存储库需要很长时间.在以下示例中是~100个子模块
git clone --recursive https://github.com/Whonix/Whonix
Run Code Online (Sandbox Code Playgroud)
Git一个接一个地克隆它们.比需要的时间长得多.让(可能)假设客户端和服务器都有足够的资源同时回答多个(并行)请求.
如何使用git clone --recursive
?加速/并行化git子模块的下载?
Von*_*onC 18
使用git 2.8(Q12016),您将能够并行启动子模块的获取!
请参阅Jonathan Nieder()提交fbf7164(2015年12月16日).
请参阅Stefan Beller()提交62104ba,提交fe85ee6,提交c553c72,提交bfb6b53,提交b4e04fb,提交1079c4b(2015年12月16日).(由Junio C Hamano合并- -在承诺187c0d3,2016年1月12日)artagnon
stefanbeller
gitster
添加一个框架以并行生成一组进程,并使用它
git fetch --recurse-submodules
并行运行" ".
为此,git fetch
有新选项:
-j, --jobs=<n>
Run Code Online (Sandbox Code Playgroud)
用于获取子模块的并行子节点数.
每个都将从不同的子模块中获取,这样获取许多子模块的速度会更快.
默认情况下,将一次提取一个子模块.
例:
git fetch --recurse-submodules -j2
Run Code Online (Sandbox Code Playgroud)
这个新功能的大部分内容是由Stefan Beller()提交c553c72(2015年12月16日).stefanbeller
run-command
:添加异步并行子处理器这允许在stderr上与有序输出并行运行外部命令.
如果我们并行运行外部命令,我们就无法将输出直接传递给我们的stdout/err,因为它会混淆.因此,每个进程的输出将流经一个管道,我们将其缓冲.一个子进程可以直接通过管道输出到stdout/err,以便向用户提供低延迟反馈.
当我运行您的命令时,下载 68 Mb 需要 338 秒的挂墙时间。
安装以下依赖于 GNU parallel 的 Python 程序,
#! /usr/bin/env python
# coding: utf-8
from __future__ import print_function
import os
import subprocess
jobs=16
modules_file = '.gitmodules'
packages = []
if not os.path.exists('Whonix/' + modules_file):
subprocess.call(['git', 'clone', 'https://github.com/Whonix/Whonix'])
os.chdir('Whonix')
# get list of packages from .gitmodules file
with open(modules_file) as ifp:
for line in ifp:
if not line.startswith('[submodule '):
continue
package = line.split(' "', 1)[1].split('"', 1)[0]
#print(package)
packages.append(package)
def doit():
p = subprocess.Popen(['parallel', '-N1', '-j{0}'.format(jobs),
'git', 'submodule', 'update', '--init',
':::'],
stdin=subprocess.PIPE, stdout=subprocess.PIPE)
res = p.communicate('\n'.join(packages))
print(res[0])
if res[1]:
print("error", res[1])
print('git exit value', p.returncode)
return p.returncode
# sometimes one of the updates interferes with the others and generate lock
# errors, so we retry
for x in range(10):
if doit() == 0:
print('zero exit from git after {0} times'.format(x+1))
break
else:
print('could not get a non-zero exit from git after {0} times'.format(
x+1))
Run Code Online (Sandbox Code Playgroud)
那个时间缩短至45秒(在同一系统上,我并没有做多的运行,以平均出波动)。
为了检查一切是否正常,我“比较”了检出的文件:
find Whonix -name ".git" -prune -o -type f -print0 | xargs -0 md5sum > /tmp/md5.sum
Run Code Online (Sandbox Code Playgroud)
在一个目录和
md5sum -c /tmp/md5sum
Run Code Online (Sandbox Code Playgroud)
在另一个目录中,反之亦然。