You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何优化Git仓库月度Python/SAS提交统计的Bash函数?

优化Git仓库按月统计Python/SAS提交次数的性能问题

原循环方案需要执行72次git log调用(36个月×2种文件),性能瓶颈明显。无循环方案的核心问题是提交行与文件名的正则匹配冲突,以及未覆盖无提交的月份,以下是修正后的可行方案:

修正后的无循环函数

function get_commits() {
    local start_date
    start_date=$(date -d "$(date +%Y-%m-01) -36 months" +%Y-%m-01)
    local end_date
    end_date=$(date -d "$(date +%Y-%m-01) +1 month" +%Y-%m-01)

    # 生成需要统计的所有月份列表,确保覆盖36个月
    local current_month="$start_date"
    declare -A all_months
    while [[ "$current_month" < "$end_date" ]]; do
        month_str=$(date -d "$current_month" +%Y-%m)
        all_months["$month_str"]=1
        current_month=$(date -d "$current_month +1 month" +%Y-%m-01)
    done

    # 打印表头
    printf "%-10s %-10s %-10s\n" "Month" "Python" "SAS"

    # 单次Git log获取全量数据,用COMMIT:前缀标记提交行,避免与文件名混淆
    git log --no-merges --since="$start_date" --until="$end_date" --pretty=format:"COMMIT:%cd %h" --date=format:'%Y-%m' --name-only -- "*.py" "*.sas" | \
    awk -v months="${!all_months[*]}" '
    BEGIN {
        OFS = "\t"
        # 初始化所有月份的计数为0
        split(months, month_arr, " ")
        for (i in month_arr) {
            py[month_arr[i]] = 0
            sas[month_arr[i]] = 0
        }
        current_commit = ""
        current_date = ""
    }
    # 识别提交行:以COMMIT:开头
    /^COMMIT:/ {
        current_date = substr($0, 8, 7)  # 提取YYYY-MM部分
        current_commit = $2
        seen_py[current_commit] = 0
        seen_sas[current_commit] = 0
        next
    }
    # 处理Python文件
    /\.py$/ {
        if (current_commit != "" && !seen_py[current_commit]++) {
            py[current_date]++
        }
    }
    # 处理SAS文件
    /\.sas$/ {
        if (current_commit != "" && !seen_sas[current_commit]++) {
            sas[current_date]++
        }
    }
    END {
        # 按月份升序输出
        PROCINFO["sorted_in"] = "@ind_str_asc"
        for (date in py) {
            printf "%-10s %-10d %-10d\n", date, py[date], sas[date]
        }
    }'
}

关键修正点

  1. 避免提交行与文件名混淆:
    在git log的格式化字符串中添加COMMIT:前缀,通过/^COMMIT:/精准识别提交行,彻底解决文件名(如2024-05.py)被误判为提交日期的问题。

  2. 覆盖所有目标月份:
    提前生成过去36个月的完整列表并初始化计数为0,确保即使某月份没有相关提交,也会输出0值,与原循环函数的输出结果保持一致。

  3. 准确关联提交与文件:
    增加current_commit和current_date变量缓存当前提交的信息,避免处理文件时丢失上下文,确保每个提交仅被计数一次(无论修改多少个同类型文件)。

  4. 使用提交日期而非作者日期:
    将%ad(作者日期)改为%cd(提交日期),与原循环函数中--since/--until的时间判定逻辑保持统一,统计结果更准确。

内容的提问来源于stack exchange,提问作者intransigent_rocker

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.14 01:23:16