更新 git repo 所需的最少网络流量是多少?

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`

蝴蝶刀刀
浏览 136回答 1
1回答

一只甜甜圈

您不必要求 git 同步完整的存储库历史记录,它通常是最方便且便宜的,可以在您在那里的时候完成。在比较它们之前尝试让 svn 和 git 做同样的事情。 svn up只关心当前的提示,对其余的根本不做任何检查。$ time git ls-remote git://github.com/torvalds/linux refs/heads/master6e8ba0098e241a5425f7aa6d950a5a00c44c9781        refs/heads/masterreal    0m0.536suser    0m0.004ssys     0m0.007s$毫不奇怪,使用 svn 和 git 检查单个远程提示所花费的时间大致相同。您当前分支的简称是git symbolic-ref -q --short HEAD(否则您不在分支上)。所以你的 svn up 正在做的更接近的等价物是if branch=`git symbolic-ref -q --short HEAD` &&     remote=`git config branch.$branch.remote` &&    merge=`git config branch.$branch.merge` &&    upstreamtip=`git ls-remote $remote $merge | cut -f1` &&    test $upstreamtip != `git rev-parse @{u}`        then git pull $remote $mergefi
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Python