【实现工作量化】GitLab代码提交量统计脚本(完整源码+详解+拓展)

简介

       起因是我想知道自己实习的近3个月写了多少代码,但是GitLab上没有现成的统计页面,然后我通过网上自己找资料方法,编写了一个基于python-gitlab库自动化统计代码提交量的脚本应对手动统计的低效问题。

        依旧是我之前的文章风格,源码+详解+拓展,大家仔细看文章,即读即用

        觉得有用的小伙伴麻烦点个赞!

        参考文章:统计gitLab开发人员的代码提交量_gitlab统计每个人的代码量-优快云博客

        参考的文章没有给出具体的源码,我这里进行了添加和拓展

详细步骤

1.安装Python

这个网上自己找攻略

一大堆

2.安装python-gitlab

打开终端输入

pip3 install python-gitlab

3.编码准备

获取公司的gitlab地址:https://git.xxx.com/

一般来说去到你的gitlab首页,复制首页地址就是

获取自己gitlab账号的private_token用于身份识别

从首页这里点击个人,然后进入设置页面

随便填个name,勾选api然后点Create就行

然后复制生成好的token备用

4.代码实现

直接看源码吧

import gitlab
from datetime import datetime, timedelta

def get_gitlab_stats(url, token, project_names, branch_names, ignore_authors=None, start_date=None, end_date=None):
    """
    统计GitLab中指定项目、指定分支和时间段内的代码提交量

    参数:
        url: GitLab服务器地址
        token: 访问GitLab的private_token
        project_names: 要统计的项目名称列表
        branch_names: 要统计的分支名称列表
        ignore_authors: 要忽略的作者列表
        start_date: 开始日期,格式为'YYYY-MM-DD',默认为7天前
        end_date: 结束日期,格式为'YYYY-MM-DD',默认为今天
    """
    # 设置默认忽略作者列表
    if ignore_authors is None:
        ignore_authors = []

    # 初始化GitLab连接
    try:
        gl = gitlab.Gitlab(url, private_token=token)
        gl.auth()  # 验证连接
        print("成功连接到GitLab服务器")
    except Exception as e:
        print(f"连接GitLab失败: {str(e)}")
        return

    # 设置默认时间范围(最近7天)
    if not end_date:
        end_date = datetime.now().strftime('%Y-%m-%d')
    if not start_date:
        start_date = (datetime.now() - timedelta(days=7)).strftime('%Y-%m-%d')

    # 转换时间格式为GitLab要求的格式
    start_time = f"{start_date}T00:00:00Z"
    end_time = f"{end_date}T23:59:59Z"

    print(f"统计时间范围: {start_date} 至 {end_date}")
    print(f"要统计的项目: {', '.join(project_names)}")
    print(f"要统计的分支: {', '.join(branch_names)}")
    if ignore_authors:
        print(f"将忽略的作者: {', '.join(ignore_authors)}")

    # 存储统计结果的字典
    stats = {}

    try:
        # 获取所有项目
        projects = gl.projects.list(all=True)
        print(f"共发现 {len(projects)} 个项目,筛选后将处理指定的项目")

        # 只处理在指定项目名称列表中的项目
        filtered_projects = [p for p in projects if p.name in project_names]

        if not filtered_projects:
            print("未找到任何匹配的项目,请检查项目名称是否正确")
            return

        print(f"找到 {len(filtered_projects)} 个匹配的项目")

        for project in filtered_projects:
            # 跳过归档项目
            if project.archived:
                print(f"项目 {project.name} 已归档,将跳过")
                continue

            print(f"\n处理项目: {project.name} (ID: {project.id})")

            try:
                # 获取项目的所有分支
                all_branches = project.branches.list(get_all=True)

                # 只保留在指定分支列表中的分支
                filtered_branches = [b for b in all_branches if b.name in branch_names]

                if not filtered_branches:
                    print(f"项目 {project.name} 中未找到任何指定的分支,将跳过该项目")
                    continue

                print(f"在项目 {project.name} 中找到 {len(filtered_branches)} 个匹配的分支")

                for branch in filtered_branches:
                    print(f"  处理分支: {branch.name}")

                    # 获取该分支在指定时间范围内的所有提交
                    commits = project.commits.list(
                        all=True,
                        query_parameters={
                            'since': start_time,
                            'until': end_time,
                            'ref_name': branch.name
                        }
                    )

                    if not commits:
                        print(f"  分支 {branch.name} 在指定时间范围内没有提交记录")
                        continue

                    print(f"  分支 {branch.name} 找到 {len(commits)} 条提交记录")

                    # 处理每个提交
                    for commit in commits:
                        # 获取提交的详细信息
                        commit_details = project.commits.get(commit.id)

                        # 获取提交者信息
                        author = commit_details.author_name
                        if not author:
                            author = "未知作者"

                        # 忽略指定作者
                        if author in ignore_authors:
                            continue

                        # 初始化作者统计数据
                        if author not in stats:
                            stats[author] = {
                                'commits': 0,       # 提交次数
                                'additions': 0,     # 新增代码行数
                                'deletions': 0,     # 删除代码行数
                                'total': 0          # 总变更行数
                            }

                        # 更新统计数据
                        stats[author]['commits'] += 1
                        stats[author]['additions'] += commit_details.stats['additions']
                        stats[author]['deletions'] += commit_details.stats['deletions']
                        stats[author]['total'] += commit_details.stats['total']

            except Exception as e:
                print(f"处理项目 {project.name} 时出错: {str(e)}")
                continue

        # 打印统计结果
        print("\n" + "="*70)
        print(f"代码提交统计 ({start_date} 至 {end_date})")
        print("="*70)

        if not stats:
            print("没有符合条件的提交记录")
            return

        # 按总变更行数排序(降序)
        sorted_authors = sorted(stats.items(), key=lambda x: x[1]['total'], reverse=True)

        # 定义各列的宽度,可根据实际情况调整
        col_widths = {
            'index': 5,
            'author': 20,
            'commits': 12,
            'additions': 12,
            'deletions': 12,
            'total': 12
        }

        # 打印表头
        header = "序号".ljust(col_widths['index']) + \
                 "作者".ljust(col_widths['author']) + \
                 "提交次数".ljust(col_widths['commits']) + \
                 "新增代码".ljust(col_widths['additions']) + \
                 "删除代码".ljust(col_widths['deletions']) + \
                 "总变更".ljust(col_widths['total'])
        print(header)
        print("-" * 70)

        # 打印带有序号的统计结果
        for index, (author, data) in enumerate(sorted_authors, 1):
            row = f"{index}".ljust(col_widths['index']) + \
                  f"{author}".ljust(col_widths['author']) + \
                  f"{data['commits']}".ljust(col_widths['commits']) + \
                  f"{data['additions']}".ljust(col_widths['additions']) + \
                  f"{data['deletions']}".ljust(col_widths['deletions']) + \
                  f"{data['total']}".ljust(col_widths['total'])
            print(row)

        print("\n" + "=" * 70)
        print("统计完成")

    except Exception as e:
        print(f"统计过程中发生错误: {str(e)}")

if __name__ == "__main__":
    # 配置信息 - 请根据实际情况修改
    GITLAB_URL = "https://git.xxx.com"  # 你的GitLab地址
    PRIVATE_TOKEN = "YOUR-PRIVATE-TOKEN"   # 替换为你的private_token

    # 要统计的项目名称列表 - 在这里添加你想统计的项目名称
    PROJECT_NAMES = [
        "project-name-1",  # 替换为实际项目名称1
        # "project-name-2",  # 替换为实际项目名称2
        # 可以继续添加更多项目名称
    ]

    # 要统计的分支名称列表 - 在这里添加你想统计的分支
    BRANCH_NAMES = [
        "master",               # 主分支
        "xx-xx-feature",         # 开发分支(示例)
        # 可以继续添加更多分支名称
    ]

    # 要忽略的作者列表
    IGNORE_AUTHORS = [
        "devops"  # 忽略名为devops的作者
    ]

    # 可以指定统计的时间范围,格式为'YYYY-MM-DD'
    START_DATE = "2025-06-10"
    END_DATE = "2025-08-31"

    # 调用统计函数
    get_gitlab_stats(
        url=GITLAB_URL,
        token=PRIVATE_TOKEN,
        project_names=PROJECT_NAMES,
        branch_names=BRANCH_NAMES,
        ignore_authors=IGNORE_AUTHORS,
        start_date,
        end_date
    )

5.功能介绍

1.支持查询指定项目

2.支持查询指定分支

3.支持查询指定时间段(没设置默认为7天内)

4.支持忽略指定作者

6.实际效果

我目前是根据总变更的行数来排序的

然后排版有点丑,各位可以自行调整

借用内容请带原文链接,觉得有用的话请点个赞吧!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值