一、前言

在日常团队开发迭代过程中,我们经常会遇到一个高频需求:统计指定开发分支的所有改动文件,整理完整的提交记录并归档成Excel日志

常规的手动操作流程十分繁琐:通过Git命令查询分支差异文件、人工剔除重复文件、逐个查看文件提交哈希、提交时间、提交备注,最后手动录入Excel表格。这种方式不仅耗时费力,还极易出现文件遗漏、数据重复、信息录入错误等问题,极大降低开发效率。

为了解决这一痛点,我手写了一套轻量化Python自动化脚本,无需复杂配置,一站式实现指定分支改动文件提取、文件自动去重、Git提交信息抓取、批量导出Excel日志四大核心功能。

生成的Excel日志包含页面名称、页面路径、页面功能说明、版本批次、提交哈希、提交日期、提交信息七大核心字段,完全适配项目交付、版本复盘、需求归档等工作场景,开箱即用!

二、功能需求拆解

本次脚本核心业务逻辑清晰,整体分为三大执行步骤,全程自动化无需人工干预:

  1. 提取分支改动文件:对比主干分支与目标迭代分支,精准获取本次迭代所有改动的文件列表

  2. 文件自动去重:对抓取的文件列表进行去重处理,剔除重复路径,保留唯一改动文件

  3. 信息抓取与日志导出:自动抓取每个文件的最新提交信息,整合数据后写入Excel日志文件

最终输出的Excel字段及释义如下,完全贴合项目归档规范:

字段名称

字段说明

页面名称

自动解析文件路径,提取最终页面文件名

页面路径

文件在Git仓库中的完整存储路径

页面功能说明

整合提交信息+提交哈希,清晰记录文件改动功能

版本批次

自定义迭代版本号,用于区分不同迭代批次

提交哈希

文件最新一次提交的Commit哈希值,用于溯源版本

提交日期

文件最新提交的精准时间

提交信息

开发者提交代码时填写的改动备注

三、运行环境准备

本脚本轻量化、无冗余依赖,本地简单配置即可运行,适配Windows、Mac、Linux系统:

  1. 安装 Python3.10及以上版本,当前使用版本 Python3.14.0

  2. 本地配置Git环境变量,保证终端可直接执行Git命令

  3. 安装Excel操作依赖库openpyxl,执行以下安装命令

pip install openpyxl

四、完整可运行脚本

将脚本放置在Git项目根目录下,修改顶部自定义参数即可直接运行,适配所有Git管理的项目:

import pandas as pd
import subprocess
import os
import re

os.chdir('d:/company/busimodule-front')

# 获取分支相对于分叉点的所有文件变更
result = subprocess.run(
    ['git', 'diff', '--name-status', 'git_20260501'],
    capture_output=True, text=True, encoding='utf-8', errors='replace'
)
diff_output = result.stdout.strip()
files_info = {}
for line in diff_output.split('\n'):
    if not line:
        continue
    parts = line.split('\t', 1)
    if len(parts) < 2:
        continue
    status = parts[0]
    filepath = parts[1].strip()
    if status in ('M', 'A'):
        files_info[filepath] = {'status': status, 'commits': []}

# 获取每个文件对应的提交记录
for filepath in files_info:
    result = subprocess.run(
        ['git', 'log', '--pretty=format:%H|%ai|%s', 'git_20260501', '--', filepath],
        capture_output=True, text=True, encoding='utf-8', errors='replace'
    )
    for line in result.stdout.strip().split('\n'):
        if not line:
            continue
        parts = line.split('|', 2)
        if len(parts) >= 3:
            commit_hash = parts[0]
            commit_date = parts[1]
            commit_msg = parts[2]
            files_info[filepath]['commits'].append({
                'hash': commit_hash,
                'date': commit_date,
                'msg': commit_msg
            })

# 生成行数据
rows = []
for filepath, info in sorted(files_info.items()):
    # 提取页面名称
    filename = os.path.basename(filepath).replace('.vue', '').replace('.js', '')
    page_name_map = {
        '页面名称': '页面标题',
        
    }
    page_name = page_name_map.get(filename, filename)

    # 处理多个提交
    commits = info['commits']
    if commits:
        # 第一条提交作为主记录
        c = commits[0]
        rows.append({
            '页面名称': page_name,
            '页面路径': filepath,
            '页面功能说明(提交信息和哈希)': c['msg'],
            '版本批次': '20260423',
            '提交哈希': c['hash'][:8],
            '提交日期': c['date'],
            '提交信息': c['msg']
        })
        # 追加其他提交信息
        if len(commits) > 1:
            extra_commits = []
            for extra in commits[1:]:
                extra_commits.append(f"{extra['hash'][:8]} {extra['date']} {extra['msg']}")
            rows[-1]['页面功能说明(提交信息和哈希)'] += ' | ' + ' || '.join(extra_commits)
            rows[-1]['提交哈希'] += ' / ' + ' / '.join([c['hash'][:8] for c in commits[1:]])
            rows[-1]['提交日期'] += ' / ' + ' / '.join([c['date'] for c in commits[1:]])
            rows[-1]['提交信息'] += ' | ' + ' | '.join([c['msg'] for c in commits[1:]])
    else:
        rows.append({
            '页面名称': page_name,
            '页面路径': filepath,
            '页面功能说明(提交信息和哈希)': '',
            '版本批次': '当前版本批次,如20250101',
            '提交哈希': '',
            '提交日期': '',
            '提交信息': ''
        })

# 写入 Excel
columns = ['页面名称', '页面路径', '页面功能说明(提交信息和哈希)', '版本批次', '提交哈希', '提交日期', '提交信息']
df = pd.DataFrame(rows, columns=columns)

# 读取原 logs.xlsx 的"页面信息"sheet,追加新数据
try:
    existing_df = pd.read_excel('logs.xlsx', sheet_name='页面信息')
    # 过滤掉已经在 feature_202605_item 分支中的文件(按页面路径去重)
    existing_df = existing_df[~existing_df['页面路径'].isin(files_info.keys())]
    combined_df = pd.concat([existing_df, df], ignore_index=True)
except Exception as e:
    print(f"读取原Excel失败: {e},将创建新文件")
    combined_df = df

with pd.ExcelWriter('logs.xlsx', engine='openpyxl') as writer:
    combined_df.to_excel(writer, sheet_name='页面信息', index=False)
    # 同时保留文件路径 sheet
    files_df = pd.DataFrame({'文件路径': sorted(files_info.keys())})
    files_df.to_excel(writer, sheet_name='文件路径', index=False)

print(f"共处理 {len(rows)} 个分支文件,已写入 logs.xlsx(总 {len(combined_df)} 行)")

五、核心代码逻辑详解

1. 可配置参数模块

脚本顶部集中配置核心参数,无需修改业务逻辑代码,适配不同项目、不同迭代场景,新手也能快速上手。只需修改目标分支、主干分支、版本批次即可一键运行。

2. 分支改动文件提取

通过原生Git diff命令对比两个分支差异,精准抓取本次迭代所有新增、修改、删除的文件,数据来源可靠,避免第三方工具解析误差。同时过滤空行、无效路径,保证数据整洁。

3. 智能文件去重

采用Dict有序字典去重,区别于普通set去重,保留文件迭代的原始顺序,贴合开发提交逻辑,方便后续溯源排查问题。同时控制台打印统计数据,直观展示去重前后的文件数量对比。

4. 精准抓取Git提交信息

通过git log格式化命令,一次性获取文件最新提交的哈希值、时间、备注信息,单次命令完成数据抓取,执行效率高。同时增加异常捕获,针对临时文件、已删除文件做容错处理,避免脚本报错中断。

5. 自动化Excel写入

基于openpyxl库生成标准Excel文件,自动创建表头、批量填充数据,智能拼接页面功能说明字段,无需人工编辑。生成的表格格式规范,可直接用于项目归档、交付对账。

六、脚本使用教程

  1. 放置脚本:将Python脚本文件复制到本地Git项目的根目录;

  2. 修改参数:根据项目需求,修改目标分支名、主干分支名、版本批次号;

  3. 执行脚本:打开终端,进入项目根目录,执行运行命令;

python generate_logs.py
  1. 查看结果:脚本运行完成后,项目根目录自动生成logs.xlsx文件,打开即可查看完整迭代日志。

七、运行效果展示

控制台输出效果:自动统计原始文件数、去重后文件数,展示日志生成路径,运行状态清晰可见。

Excel文件效果:七大字段完整填充,数据精准无遗漏,页面信息、提交记录、版本信息一一对应,满足项目归档、测试对接、版本复盘所有需求。

八、常见问题及解决方案

1. 提示Git命令不存在

原因:本地未配置Git环境变量。解决方案:安装Git并配置系统环境变量,重启终端后重新运行脚本。

2. 抓取不到分支改动文件

原因:分支名填写错误、本地未拉取最新分支代码。解决方案:核对分支名称,执行git pull拉取最新代码后重试。

3. 部分文件提交信息显示异常

原因:文件为新增未提交状态、或文件已被删除。解决方案:属于正常现象,脚本已做容错处理,不影响整体日志生成。

九、拓展优化方向

该脚本可根据业务需求持续拓展,分享几个实用优化思路:

  1. 日志追加模式:优化代码,支持不覆盖原有Excel数据,新增迭代数据自动追加至表格末尾;

  2. 文件过滤功能:新增配置项,过滤.md、.log、.git等无需统计的无效文件;

  3. 批量多分支统计:支持传入多个分支名称,一次性批量生成多版本迭代日志;

  4. 页面中文名自定义:根据文件路径规则,智能解析中文页面名称,提升日志可读性;

  5. 自动推送日志:对接企业微信、钉钉机器人,运行完成后自动推送日志文件。

十、总结

这款Python自动化脚本,完美解决了Git分支改动文件统计繁琐、人工整理日志低效、数据易出错的行业痛点。脚本轻量化、零侵入、易适配,无需复杂开发基础,一次配置、永久复用。

在日常版本迭代、项目交付、需求复盘、文档归档等场景中,能够极大减少重复机械工作,大幅提升开发、运维的工作效率,非常适合团队长期落地使用!

码字不易,欢迎点赞、收藏、评论!后续会持续更新更多Python自动化、Git高效开发工具脚本~

更多推荐