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

Git历史提交未合并分支统计需求:含已删分支及按时间统计

如何查询Git历史时点的未合并分支数量(含已删除分支)及按周期统计

我来帮你拆解这个问题,分两部分解决:先搞定历史特定时点的未合并分支统计(包括后来被删除的分支),再实现按日/过去X天/月的周期统计。


1. 查看指定历史时点的未合并分支数量(含已删除分支)

Git本身不会主动保存分支的历史状态,但我们可以通过reflog(分支操作日志)和commit历史来还原当时的场景。

步骤1:确定目标时点的master分支状态

首先得拿到你要查询的那个时间点,master分支的最新提交哈希——毕竟我们要对比的是当时的master,不是现在的。

  • 如果用具体日期指定时点(比如2023年12月31日):
TARGET_DATE="2023-12-31 23:59:59"
# 找到该日期前master的最后一个提交
MASTER_AT_TARGET=$(git log --before="$TARGET_DATE" --pretty=format:"%H" master | head -1)
  • 如果已经知道目标时点的commit哈希,直接赋值就行:
MASTER_AT_TARGET="abc123def456..."

步骤2:提取所有曾经存在过的远程分支

Git的reflog会记录所有分支的操作(包括创建、删除、更新),我们可以从中提取所有出现过的远程分支:

# 过滤出所有远程分支名称,去重后得到完整列表
ALL_REMOTE_BRANCHES=$(git reflog show --all | grep -E 'origin/[^ ]+' | awk '{print $5}' | sort | uniq)

注:如果你的远程仓库不是默认的origin,把命令里的origin/换成你的远程名称即可。

步骤3:统计未合并分支数量

遍历每个曾经的远程分支,找到它在目标时点的最新提交,再判断这个提交是否没被合并到当时的master:

UNMERGED_COUNT=0
for BRANCH in $ALL_REMOTE_BRANCHES; do
    # 获取该分支在目标时点的最后一个提交
    BRANCH_COMMIT_AT_TARGET=$(git log --before="$TARGET_DATE" --pretty=format:"%H" "$BRANCH" | head -1)
    # 如果该分支在当时存在(有有效提交)
    if [ -n "$BRANCH_COMMIT_AT_TARGET" ]; then
        # 判断该提交是否未被合并到当时的master
        # 如果merge-base返回非0,说明未合并
        if ! git merge-base --is-ancestor "$BRANCH_COMMIT_AT_TARGET" "$MASTER_AT_TARGET"; then
            UNMERGED_COUNT=$((UNMERGED_COUNT + 1))
        fi
    fi
done
# 输出统计结果
echo "在目标时点未合并到master的分支数量:$UNMERGED_COUNT"

2. 按每日/过去X天/月统计未合并分支数量

核心思路就是遍历每个时间节点(比如每天的结束时点),重复上面的统计逻辑,然后输出每个时间点的结果。

示例:统计过去30天每天的未合并分支数量

下面的脚本会自动遍历过去30天的每一天,输出每天的未合并分支数:

# 定义统计的起始和结束日期(这里是过去30天到昨天)
START_DATE=$(date -d "-30 days" +%Y-%m-%d)
END_DATE=$(date -d "-1 day" +%Y-%m-%d)

CURRENT_DATE="$START_DATE"
# 循环遍历每一天
while [ "$CURRENT_DATE" != "$(date -d "$END_DATE +1 day" +%Y-%m-%d)" ]; do
    # 设置当天的结束时点(确保统计的是当天完整状态)
    TARGET_DATE="$CURRENT_DATE 23:59:59"
    # 获取当天master的最后一个提交
    MASTER_AT_TARGET=$(git log --before="$TARGET_DATE" --pretty=format:"%H" master | head -1)
    
    # 如果当天master没有有效提交(比如仓库刚创建),跳过统计
    if [ -z "$MASTER_AT_TARGET" ]; then
        echo "$CURRENT_DATE: 无有效master提交"
        CURRENT_DATE=$(date -d "$CURRENT_DATE +1 day" +%Y-%m-%d)
        continue
    fi
    
    # 统计当天的未合并分支数量
    UNMERGED_COUNT=0
    ALL_REMOTE_BRANCHES=$(git reflog show --all | grep -E 'origin/[^ ]+' | awk '{print $5}' | sort | uniq)
    for BRANCH in $ALL_REMOTE_BRANCHES; do
        BRANCH_COMMIT_AT_TARGET=$(git log --before="$TARGET_DATE" --pretty=format:"%H" "$BRANCH" | head -1)
        if [ -n "$BRANCH_COMMIT_AT_TARGET" ]; then
            if ! git merge-base --is-ancestor "$BRANCH_COMMIT_AT_TARGET" "$MASTER_AT_TARGET"; then
                UNMERGED_COUNT=$((UNMERGED_COUNT + 1))
            fi
        fi
    done
    
    # 输出当天的统计结果
    echo "$CURRENT_DATE: $UNMERGED_COUNT"
    # 日期加1天,进入下一轮循环
    CURRENT_DATE=$(date -d "$CURRENT_DATE +1 day" +%Y-%m-%d)
done

实用优化建议

  • 如果统计周期很长(比如几个月),上面的脚本会比较慢——可以提前把所有分支的历史commit时间导出到一个文件,批量处理能大幅提升效率。
  • 要按月份统计的话,只需要把日期遍历改成每月的最后一天即可,比如用date -d "$YEAR-$MONTH-01 +1 month -1 day" +%Y-%m-%d生成每月最后一天的日期。
  • 注意:Git的reflog默认只保留90天的记录,如果要查询更早的历史,得确保仓库的reflog没被清理,或者你有之前备份的refs目录。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.26 09:18:57