【无标题】

自动从私有 GitLab 服务器批量拉取(或克隆)项目代码,并同步所有远程分支的最新内容到本地

代码

# ==============================================
# 说明:
# gitLab需要配置成自己的参数
# groupName为空则拉取所有项目,否则拉取group下面的项目
# ==============================================
import tkinter as tk
from tkinter import filedialog
from urllib.request import urlopen
import json
import os
from git.repo import Repo
from concurrent.futures import ThreadPoolExecutor, as_completed
import threading

# 配置gitLab
gitlabAddr = "--" # 192.168.1.1:80
gitlabPrivateToken = "--" # 访问令牌
groupName = ""

# 设置本地存储路径
root = tk.Tk()
root.withdraw()
folderPath = r"--"  # D:/gitlab

# 构建 API URL
if groupName == "":
    url = f"http://{gitlabAddr}/api/v4/projects?private_token={gitlabPrivateToken}&per_page=1000&order_by=name"
else:
    # 注意:GitLab v4 API 中 groups 的 projects 接口路径已变更
    url = f"http://{gitlabAddr}/api/v4/groups/{groupName}/projects?private_token={gitlabPrivateToken}&per_page=1000&order_by=name"

print("Fetching projects from:", url)

# 获取项目列表
with urlopen(url) as response:
    allProjectsDict = json.loads(response.read().decode("UTF-8"))

# 反转顺序(可选)
allProjectsDict.reverse()

# 线程安全的日志打印
print_lock = threading.Lock()


def log(msg):
    with print_lock:
        print(msg)


def sync_project(thisProject):
    try:
        thisProjectURL = thisProject["http_url_to_repo"]
        thisProjectPath = thisProject["path_with_namespace"]
        filePath = os.path.join(folderPath, thisProjectPath)

        log(f"Processing: {thisProjectURL} -> {filePath}")

        if os.path.exists(filePath):
            repo = Repo(filePath)
            log(f"  -> Pulling existing repo: {filePath}")
        else:
            os.makedirs(os.path.dirname(filePath), exist_ok=True)
            repo = Repo.clone_from(thisProjectURL, filePath)
            log(f"  -> Cloned new repo: {filePath}")

        remote = repo.remote()
        remote_branch_names = [
            ref for ref in remote.refs if not ref.remote_head.startswith("HEAD")
        ]

        for ref in remote_branch_names:
            branch_name = ref.remote_head
            try:
                repo.git.checkout(branch_name, force=True)
                repo.git.pull()
                log(f"    -> Updated branch: {branch_name}")
            except Exception as e:
                log(f"    !! Error pulling branch {branch_name} in {filePath}: {e}")

    except Exception as e:
        log(
            f"!! Failed to process {thisProject.get('http_url_to_repo', 'unknown')}: {e}"
        )


# 并发执行
max_workers = 10  # 可根据网络和磁盘性能调整
with ThreadPoolExecutor(max_workers=max_workers) as executor:
    futures = [executor.submit(sync_project, project) for project in allProjectsDict]
    for future in as_completed(futures):
        # 异常已在 sync_project 内部处理,此处可选是否 re-raise
        pass

log("All projects synchronized.")

🎯 这段代码的作用:

自动从 GitLab 下载(或更新)你所有的项目代码到本地电脑。

就像你手动一个个点“克隆”或“拉取更新”一样,但它能一次性自动做完所有项目,还支持多任务同时进行,省时省力。


🔧 你需要改的地方(配置):

  1. GitLab 地址:比如 192.168.1.1:80
  2. 你的访问令牌(Private Token):在 GitLab 账号里生成,用来证明你是谁。
  3. 要不要只下载某个组(groupName)的项目?
    • 留空 → 下载你有权限的所有项目
    • 填名字 → 只下载这个组里的项目
  4. 本地保存路径:比如 D:/gitlab,所有代码会存到这里,按原项目结构组织(如 公司/部门/项目名

🔄 它是怎么工作的?

  1. 先问 GitLab:“我有哪些项目?”(通过 API 获取列表)
  2. 对每个项目
    • 如果本地没有这个项目 → 就 git clone 下来
    • 如果本地已经有 → 就 git pull 更新最新代码
  3. 还会把每个项目的每个分支都更新一遍(这点可能有点多,一般只需要主分支)
  4. 多个项目可以同时下载/更新(最多10个一起跑),更快!

✅ 举个例子:

假设你在 GitLab 有这些项目:

  • mygroup/backend
  • mygroup/frontend

运行脚本后,它会在你电脑上自动创建:

D:/gitlab/mygroup/backend/
D:/gitlab/mygroup/frontend/

并且确保它们都是最新代码。


⚠️ 注意:

  • 你需要提前安装 Python 和几个库(比如 gitpython
  • 如果项目特别多(超过1000个),可能需要改代码支持分页
  • 群组名字如果带斜杠(比如 parent/group),可能要特殊处理

💡 总结一句话:

这是一个“一键同步 GitLab 所有项目到本地”的自动化小工具。

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值