git很慢,让我们自动化
上下文是我想编写一个更新约 150 个 git 存储库的脚本。与我们之前的 subversion 安装相比,Gitlab/hub 在网络上的速度几乎慢了一个数量级,例如:
(dev) go|c:\srv\lib\examradar> python -c "import time;start=time.time();import os;os.system('svn up');print time.time() - start"
Updating '.':
At revision 31294.
0.559000015259
(dev) go|c:\srv\lib\code\dkrepo> python -c "import time;start=time.time();import os;os.system('git pull');print time.time() - start"
Already up to date.
Current branch master is up to date.
4.31999993324
IE。150 个 svn 存储库至少需要 84 秒,而 150 个 git 存储库将需要 10 分钟以上(!)(在 win10 上的 wsl 上的 ubuntu 中运行相同的命令会产生 0.48 秒和 1.52 秒——看图 ;-)
使用脚本,我们可以并行执行所有“简单”更新,并将 git-case 缩短到约 100 秒。不幸的是,我们遇到了超时(经常这样做git rev-parse @{u}),所以我正在寻找最有效的方法来更新 git repo 并善待 git 服务器。
我对“作弊”持开放态度,例如,如果在 git 之外有办法知道(很有可能)不需要更新 repo(webhooks?,后台 fetch-daemons?)
搞砸回购是非常具有破坏性的,所以如果拉动会产生合并冲突,它应该保释。
当前代码
我正在使用 python 调用包来简化调用命令。我也会对只使用原始 git 命令的答案感到满意。这是我到目前为止...
首先是一个便捷函数,它打印正在运行的命令及其输出,并将输出作为字符串返回:
from invoke import task
def runner(c):
return lambda cmd: c.run(cmd, hide=False, echo=True).stdout.strip()
然后是获取回购状态的任务/功能。我相信只有git fetch和 git rev-parse @{u}` 接触网络(?):
@task
def get_status(c, wc):
"""Return a set containing the strings
local-clean if there are no local changes
local-dirty if there are local changes
untracked if there are files that haven't been added to git
remote-change if upstream has changed
local-change if there are local committed (but not pushed) changes
diverged if local and upstream have diverged
"""
run = runner(c)
with c.cd(wc):
status = []
porcelain = run('git status --porcelain')
if porcelain == "":
status.append('local-clean')
else:
status.append('local-dirty')
untracked = run('git ls-files --others --exclude-standard')
if untracked:
status.append('untracked')
run('git fetch') # only interested in current branch so not using `git remote update`
一只甜甜圈
相关分类