并行执行"git submodule foreach"

cbu*_*art 5 git parallel-processing git-submodules

有没有办法git submodule foreach并行执行命令,类似于--jobs 8参数的工作方式git submodule update

例如,我们工作的项目之一涉及近200个子组件(子模块),我们大量使用该foreach命令对它们进行操作.我想加快它们的速度.

PS:如果解决方案涉及脚本,我在Windows上工作,大多数时候,使用git-bash.

RDC*_*106 4

我向您推荐一个基于解释语言多平台(如 Python)的解决方案。


进程启动器


首先,您需要定义一个类来管理启动命令的过程。

class PFSProcess(object):
    def __init__(self, submodule, path, cmd):
        self.__submodule = submodule
        self.__path = path
        self.__cmd = cmd
        self.__output = None
        self.__p = None

    def run(self):
        self.__output = "\n\n" + self.__submodule + "\n"
        self.__p = subprocess.Popen(self.__cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True,
                             cwd=os.path.join(self.__path, self.__submodule))
        self.__output += self.__p.communicate()[0].decode('utf-8')
        if self.__p.communicate()[1]:
            self.__output += self.__p.communicate()[1].decode('utf-8')
        print(self.__output)
Run Code Online (Sandbox Code Playgroud)


多线程


下一步是生成多线程执行。Python 在其核心中包含非常强大的库来处理线程。您可以使用它导入以下包:

import threading
Run Code Online (Sandbox Code Playgroud)

在创建线程之前,您需要创建一个工作线程,一个为每个线程调用的函数:

def worker(submodule_list, path, command):
    for submodule in submodule_list:
        PFSProcess(submodule, path, command).run()
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,工作人员收到了一个子模块列表。为了清楚起见,并且因为它超出了我们的范围,我建议您查看一下.gitmodules可以生成读取文件的子模块列表的位置。


<提示>

作为基本方向,您可以在每个子模块中找到以下行:

path = relative_path/project
Run Code Online (Sandbox Code Playgroud)

为此,您可以使用以下正则表达式:

path = relative_path/project
Run Code Online (Sandbox Code Playgroud)

如果正则表达式匹配,您可以在同一行中使用以下内容获取相对路径:

'path ?= ?([A-za-z0-9-_]+)(\/[A-za-z0-9-_]+)*([A-za-z0-9-_])'
Run Code Online (Sandbox Code Playgroud)

请注意,最后一个正则表达式返回的相对路径在第一个位置有一个空格字符。

</提示>


然后将子模块列表分成与您想要的作业一样多的块:

' ([A-za-z0-9-_]+)(\/[A-za-z0-9-_]+)*([A-za-z0-9-_])'
Run Code Online (Sandbox Code Playgroud)

最后将每个块(作业)分派给每个线程并等待所有线程完成:

num_jobs = 8

i = 0
for submodule in submodules:
    submodule_list[i % num_jobs].append(submodule)
    i += 1
Run Code Online (Sandbox Code Playgroud)


显然我已经暴露了基本概念,但是您可以访问GitHub 中的parallel_foreach_submodule (PFS)项目来访问完整的实现。