并行执行git子模块Foreach(&Q) [英] Execute "git submodule foreach" in parallel
本文介绍了并行执行git子模块Foreach(&Q)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
有没有办法并行执行git submodule foreach
命令,类似于--jobs 8
参数与git submodule update
的工作方式?
例如,我们参与的一个项目涉及近200个子组件(子模块),我们大量使用foreach
命令对其进行操作。我想加快速度。
PS:在解决方案涉及脚本的情况下,我在Windows上工作,大多数情况下使用git-bash。
推荐答案
我为您提供一个基于解释语言多平台的解决方案,如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 = "
" + self.__submodule + "
"
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)
多线程
下一步是生成多线程执行。在其核心中,Python包含了用于处理线程的非常强大的库。您可以使用它导入以下程序包:
import threading
在创建线程之前,您需要创建一个Worker,即为每个线程调用的函数:
def worker(submodule_list, path, command):
for submodule in submodule_list:
PFSProcess(submodule, path, command).run()
如您所见,Worker收到一个子模块列表。为了清楚起见,并且因为它超出了我们的范围,我建议您查看一下.gitmodules
,在那里您可以生成读取该文件的子模块的列表。
💡<;提示>
作为基本方向,您可以在每个子模块中找到以下行:
path = relative_path/project
为此,可以使用以下正则表达式:
'path ?= ?([A-za-z0-9-_]+)(/[A-za-z0-9-_]+)*([A-za-z0-9-_])'
如果正则表达式匹配,则可以在同一行中使用以下内容获取相对路径:
' ([A-za-z0-9-_]+)(/[A-za-z0-9-_]+)*([A-za-z0-9-_])'
请注意,因为最后一个正则表达式返回的是第一个位置带有空格字符的相对路径。
💡<;/提示>
然后将子模块列表拆分成与作业一样多的块:
num_jobs = 8
i = 0
for submodule in submodules:
submodule_list[i % num_jobs].append(submodule)
i += 1
最后将每个块(作业)分派到每个线程,并等待所有线程完成:
for i in range(num_jobs):
t = threading.Thread(target=worker, args=(list_submodule_list[i], self.args.path, self.args.command,))
self.__threads.append(t)
t.start()
for i in range(num_jobs):
self.__threads[i].join()
显然,我已经介绍了基本概念,但您可以在GitHub中访问parallel_foreach_submodule (PFS)项目的完整实现。
这篇关于并行执行git子模块Foreach(&Q)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文