使用Git图形化管理工具SourceTree
好多年,去年起SourceTree
越更新越辣鸡,简直不能用,转而投了Fork
的怀抱,但是两者都没有批量拉取的功能.
然而负责的项目越来越多,而单个拉取仓库更新代码无异是痛苦的.
于是花了点功夫看了下官方的API文档,写了个用Python批量拉取所有仓库的脚本,使用了一个第三方的 Python 模块: python-gitlab
.
功能很简单,就是根据账号权限并发拉取所有能拉取的仓库,如果当前目录下不存在就创建;如果已存在仓库,则更新.
import platform,os,gitlab,sys,multiprocessing
def returnpath(path:str)->str:
if 'Windows' == platform.system():
path = path.replace('/','\\')
return path
def get_gitlab_groups_projs_path(gl_server:gitlab.Gitlab)->list:
projs = []
projs_id = []
projs_tmp = []
def __add(group):
for proj in group.projects.list():
projs_tmp.append({'id':proj.attributes.get('id'),'proj_path':proj.attributes.get('path_with_namespace'),
'group_path':proj.attributes.get('namespace').get('full_path'),
'url':proj.attributes.get('http_url_to_repo')
})
for group in gl_server.groups.list(order_by='id',all_available=True):
__add(group)
sgs = group.subgroups.list(lazy=True)
for sg in sgs:
sg_attr = sg.attributes
__add(gl_server.groups.get(sg_attr.get('id')))
for proj in projs_tmp:
if proj.get('id') not in projs_id:
projs.append(proj)
projs_id.append(proj.get('id'))
return projs
def multi_process(num,func,infos,commit):
task_pool = multiprocessing.Pool(num)
for info in infos:
task_pool.apply_async(func,args=(info,commit,))
task_pool.close()
task_pool.join()
def get_repo(info:dict,*args):
cmd = 'cd ' + os.getcwd() + returnpath('/')
if os.path.exists(path=info.get('proj_path')):
cmd += info.get('proj_path') + ' && git pull'
else:
cmd += info.get('group_path') + '&& git clone ' + info.get('url')
os.system(cmd)
def push_repo(info:dict,commit:str):
proj_path = info.get('proj_path')
if os.path.exists(path=proj_path):
cmd = 'cd ' + os.getcwd() + returnpath('/') + proj_path + '&& git pull && git commit -am "' + commit + '" && git push'
os.system(cmd)
else:
print('Not exit ' + proj_path)
if __name__ == "__main__":
action = ''
if len(sys.argv) < 2 :
print("参数过少.\neg: "+sys.argv[0]+' pull')
sys.exit(1)
else:
action = sys.argv[1]
git_addr = "http://gitlab.addr:port" # gitlab服务器地址
token = '8Q_uudHvJsNBTApedU5V' # 账号的token,在个人页面的Setting - Access Tokens 中创建
processNum = 5
gl_server = gitlab.Gitlab(url=git_addr, private_token=token)
infos = get_gitlab_groups_projs_path(gl_server=gl_server)
# sys.exit(0)
for proj in infos:
if not os.path.exists(path=proj.get('group_path')):
os.makedirs(proj.get('group_path'))
if not os.path.exists(path=returnpath('TL')):
processNum = 3
print(processNum)
if 'pull' == action:
multi_process(num=processNum,func=get_repo,infos=infos,commit='')
elif 'push' == action:
commit = 'Batch Edit'
multi_process(num=processNum,func=push_repo,infos=infos,commit=commit)
else:
print('Unkonw action.')