levfan

git-commit

本项目(excel2mysql)的提交纪律:每一次改动写完并通过验证就立即按性质拆分 commit 并推送到 origin/main,不等用户开口;验证不通过不提交;凭据、构建产物、敏感路径永不入库。适用于写完一段代码/修一个 bug/补一次文档之后的收尾动作。

levfan 1 Actualitzat fa 1 d
GitHub

Instal·la

npx skillscat add levfan/excel2mysql/git-commit

Instal·la des del registre de SkillsCat.

SKILL.md

excel2mysql 提交规范

核心规则:改完 + 验证通过 = 立刻提交推送

  • 每一次改动(不要求攒成一个"功能")写完并通过验证后,立即产生 commit 并推送,
    不把工作区长期留着未提交状态,不需要等用户开口
  • 验证不通过禁止提交:红的不进库;先修到绿再走提交流程
  • 一次会话里做了多件事,就按性质拆成多个 commit;不同性质禁止混进同一个 commit
  • 顺序固定:确认验证通过 → 扫一遍待提交内容 → git add <具体路径> → git commit
    → git pull --no-rebase origin main → git push origin main
  • 远端:https://github.com/levfan/excel2mysql.git,分支 main,upstream 已配置
  • 推送失败(凭据/网络/非快进)时:保留本地 commit,报告原因等用户处理;
    禁止 force push、禁止 git pull --rebase 改写已推送的历史

验证口径(按改动类型选,别一律跑全套)

改动类型 必须跑的东西 通过标准
逻辑/数据路径改动(main.py / core/*.py / ui_help.py / help_doc.py 的行为部分) .venv/Scripts/python.exe pack_test.py 退出码 0 且汇总 失败 0
纯外观改动(字号 / 颜色 / 间距 / 纯文案,不改行为) 只跑直接咬住它的那几条:读真控件的探针、对应自检或单条断言、py_compile;改到 Java 就再编译那一个模块 探针/自检退出码 0;断言改过就做变异抽查
只改测试用例 pack_test.py 同上(用例自己就是被测对象) 退出码 0
打包口径(*.spec / _pack_common.py / build_exe.py / 一键打包-图形版.bat) 先 pack_test.py,再 build_exe.py 全闸门 闸门 7 步全过、产物能起窗
纯文档(README.md / help_doc.py 文案 / .agents/**) 自检即可:frontmatter 合法、路径存在、无待办占位;help_doc.py 改动要能 import 且 pack_test.py 的 P 组不红 上述检查通过
  • 外观改动不跑全量(用户 2026-10-24 原话:"这只是改字体,不涉及功能修改,不需要跑全部夹具或者用例")。
    分档判据只看一件事:这个改动会不会改变行为。只动字体/字号/颜色/间距/纯文案 →
    针对性验证就够(离屏探针读真控件、对应自检、改到的那一端编译);动了推断、读取、
    DDL、导入、命名、脚本改写这类数据路径 → 才按全量闸门跑。拿不准按"会改行为"处理。
    别为了显得严谨把整套夹具跑一遍:那既慢,又把"这次到底验了什么"埋进几千行输出里。

  • "全绿"必须拿退出码:echo $? 为 0 才算过,不能靠肉眼看输出里有没有 FAIL

  • 新增/修改断言后,要做一次变异抽查:把对应产品代码故意改坏,确认用例真的变红,
    再逐字节还原。写一条咬不住的断言比不写更糟

  • 跑 G 组(真实 MySQL)每次都要带上凭据跑,不要回问用户,载入方式见下面
    「本机测试库」一节;只有端口真连不通时才按"未覆盖"显式记账

  • 打包(PyInstaller)只在用户明说"打包"时才做,与提交规则互不覆盖:
    提交是每次改动的收尾动作,打包是单独指令

本机测试库(G 组每次都跑,不再问用户)

用户 2026-10-22 原话:"测试库的环境是……这个你可以写到项目 skills 中,不要每次都问我。"
所以这事以后不再确认:

  • 环境:127.0.0.1:3306,用户 root,库 testdb。服务端是 WSL 里 docker 容器 mysql8
    的 MySQL 8.0.46(utf8mb4_unicode_ci,STRICT_TRANS_TABLES 开着)。
    这就是拿来折腾的测试库:G 组会建表、导入、查询、回滚,只动
    packtest_probe* / e2m* 这类探针名,不碰别的表。

  • 口令放在仓库根的 .pt_env(.gitignore 里 /.pt_env 那条已经把它挡在库外),
    内容是 PT_USER / PT_PASS / PT_DB / PT_HOST / PT_PORT 五行 export。
    口令本身不进任何被跟踪的文件,包括本技能:远端是公开仓库,写进一次 commit
    就永久留在历史里,事后删文件撤不掉。本技能只写"怎么载入"。

  • 跑法(Git Bash,仓库根目录):

    set -a; . ./.pt_env; set +a
    .venv/Scripts/python.exe pack_test.py        # 图形线,G1-G9 应当真跑
    .venv38/Scripts/python.exe pack_test38.py    # Win7 线
    .venv/Scripts/python.exe pack_test38.py      # 同一套在新栈上再跑一遍
  • 判据:带凭据跑之后 G 组一条 SKIP 都不许留。端口连不通(WSL/docker 没起)才算
    "未覆盖",汇报时要说清是端口不通、不是没配凭据。只报 Q 组绿不等于证明过
    生成的 DDL 能被 MySQL 接受——那是假连接,两件事在报告里必须分开说。
    带凭据时剩下的 SKIP 只有 PT_XLS(本机没有 .xls 样本)与冻结态专属项那几条,
    它们与凭据无关,别把它们当成"G 组还没跑"。

  • .pt_env 不在了就回问用户要口令(不自行编造、不从别处猜),拿到后重新落一份
    同样不入库的文件;这条是"不再每次问"的唯一例外。

  • 跑前扫一眼 testdb 里有没有上一轮被中断留下的 packtest_probe / packtest_probe_bad:
    G 组会 DROP 同名表,残留会被读成这一轮的产物。

收尾必做的一步:评估要不要升版本号

用户 2026-10-23 定的规则:"做完一个功能的时候,或者修复完一个问题的时候,你需要评估是否需要升级版本号。"
所以每一次收尾,除了跑验证与提交,还要显式判断版本号动不动,并把结论和一句理由写进汇报里
(升与不升都要说,不说不等于判断过)。

判据(本项目口径):

先答一个问题,再定档位:这轮之后,老版本用户有没有"以前做不到、现在能做"的一件事?

  • 有,且老做法原样还能用 → 升 minor(2.0.x → 2.1.0)。新增页签、新增按钮、
    新增一类交互、新增一条执行/处理通道(例如整库 dump 走逐条提交、手写脚本仍走按文件
    事务)、新增开关、CLI 新增参数、新增产物形态、交付件里新增可选字段,全在这一档
  • 没有,只是"以前那件事现在做得更对 / 更稳 / 更快 / 更好看" → 升 patch
    (2.1.0 → 2.1.1)。缺陷修复、文案订正、字号颜色间距、内部实现替换而输入输出形状不变
  • 老做法不能原样用了 → 升 major(2.x → 3.0.0)。同输入产出不同含义的结果且
    不告知就升级会出事:conn.ini 键位改名、CLI 参数含义变化、产物目录结构与启动方式变化、
    交付件形状旧版读不了、去掉或合并一个既有能力、执行语义从"可回滚"变成"已落库"这类
    用户已依赖的承诺改变
  • 只改测试用例、只改文档、只改构建脚本且不影响交付物 → 不升,在提交信息里写明"版本号不动"
  • 一次会话做了多件事:按其中最重的一档定,一次升到位,不要每个 commit 升一次;
    升 minor 时 patch 归零(2.0.10 的新能力 → 2.1.0,不是 2.0.11)
  • 已经交付过某个版本再改东西 → 必须升,不能让用户手上两个同名包内容不同
  • 兜底:patch 升到 2.0.9 之后还要再升,先停下来重判——一路只升 patch 通常意味着
    把"新增能力"错记成了"修复"。本项目 2026-10-25 就被用户抓到这一条:dump 执行通道、
    脚本清单、交互引导样式都是"以前做不到现在能做",却连着升成 2.0.6…2.0.10,
    更正为 2.1.0
  • major 不攒着等"大 rewrite":判据命中就升,哪怕只改一处不兼容;宁可 3.0.0 早点出现,
    也不要让用户按 2.x 理解一个语义已经变了的包

改哪里:取值唯一来自 version.py 的 APP_VERSION(窗口标题、《关于》、--version、随包 appinfo 都读它),
但另有 8 处写死的字符串要跟着一起改——三个 pom.xml(根 pom 的 <version> 与 <app.version>、
app/verify 的 <parent><version>)、java/构建验证.bat 里的 jar 名、help_doc.py 与
java/assets/conn.ini 示例命令里的 jar 名、README 顶部那行与几处路径示例。
pack_test.py 的 T15 逐处把这些字符串与 APP_VERSION 核一遍:改版本前先跑一次确认起点干净,
改完再跑一次确认没漏
;产物目录名 excel2mysql-java-<版本>-win64 随 pom 自动变,不用手改。
升过版本就要按"打包按需触发"的规矩等用户开口才重打交付包,但要在汇报里点明"包还是旧版本"。

按开发阶段命名版本(alpha / beta / rc)

用户 2026-10-23 补的口径:"版本号类型有 rc,alpha 等,按照开发阶段进行版本号命名。"
阶段是版本的属性,不是另开一条号段,所以后缀就写在 APP_VERSION 里(仍然只有这一个来源):
1.1.0-alpha.1、1.1.0-beta.2、1.1.0-rc.1。窗口标题、《关于》、--version、jar 名、
产物目录名会自动带上后缀,T15 也按整段核——只截 X.Y.Z 的话,"1.1.0-rc.1 vs 1.1.0"
会被判成一致,那正是这条守卫要拦的漏改。

三种后缀各自代表"这版能承诺到哪一步",别拿来当装饰:

  • -alpha.N:这一批功能还没收口,界面上还会变。只发给内部或明确愿意容忍改动的人,
    不要拿去装现场机器
  • -beta.N:功能收口、五道闸门全过,但还没在真实环境验过(客户的 MySQL 版本、
    真实那批 Excel、现场的系统版本)。给自愿试点的人,同时说清验收还没做
  • -rc.N:只剩验收结论没拿回来。期间不加功能,只修阻断性缺陷;每修一处就进一个序号
  • 转正:1.1.0-rc.2 验收通过 → 发 1.1.0,号不变、只去后缀(不要再 +1,否则
    "1.1.0 才是正式版"这个承诺反而多了一次版本跳跃)。rc 期间若改了用户可见行为,
    它就不再是"候选",抬一档(patch 或 minor)重新从 -rc.1 起

默认不带后缀:这条线的产物是要装到现场办公机上的工具,包名里带 rc 等于自己承认
"这版不算数",现场验收凭证上不该出现这种字样;三端产物已经发出去过,后续每一次收尾
直接升 patch/minor 就是正式版。只有当用户明确说"先给一版试试、还不作数"的时候才加后缀。
一次会话里加了后缀,就要在汇报里写清"这版是候选,转正时去掉后缀、号不变",
否则下一轮收尾会不知道接着升哪儿。

机器判定:T1 只放行 X.Y.Z 或 X.Y.Z-(alpha|beta|rc).N(rc1、rc、release
这类写法一律红);序号从 1 起、用点号分隔,是为了让后缀能机器判读,也为了 Maven 的
版本序(1.1.0-rc.1 < 1.1.0)与文件名排序同向。

拆分与提交信息

type(scope): 祈使句中文描述,不超过 50 字,结尾不加句号
  • type:feat / fix / test / docs / refactor / perf / build / chore
  • scope 用本项目真实模块:gui(main.py 界面)、infer(core/infer.py 类型与命名)、
    zip(core/zip_import.py)、merge(core/merge_check.py)、sql(core/sql_script.py)、
    naming(core/naming.py)、mysql(core/mysql_io.py)、progress(进度框与子线程)、
    help(help_doc.py / ui_help.py 使用说明)、pack(打包与 spec)
  • body 写动机与影响,不逐文件罗列;用 heredoc 传多行消息避免转义事故
  • 主题行与正文之间必须空一行:只给一个换行的话 git 会把整段并成 subject,
    git log --oneline 与 GitHub 提交列表里会拖出一条超长标题
    (本项目 121dded / 5534cd5 / c2f4a33 三个提交就踩了;已推送的不改写历史,此后必须避免)
  • 提交后立刻复核格式:git log -1 --format=%s 只应有一行且 ≤50 字,git log -1 --format=%b 应非空
  • 本项目没有数据库迁移脚本,不要套用"db 独立成 commit"那类外部规则

示例(一次带测试的功能改动 = 两个 commit,注意每个提交内部的空行):

feat(naming): 新增「替换首个前缀」按首段改写表名

换掉第一个下划线之前那段,ods_t_order → change_t_order。

test(naming): 覆盖首段切分、撞名去重与 SQL 引用同步改写

32 条断言,含跳过的表也计入进度项。

入库红线

  • 提交前必须 git add 具体路径并 git status 复核;禁止无脑 git add -A
  • 提交前扫一遍待提交内容有没有口令与内部标识:
    git diff --cached | grep -inE "PT_PASS=|password.*=.*['\"].{4,}|token|<内部项目代号>"
    (本技能自己写着这条模板,改 .agents/** 时它会命中本文件那一行,属预期命中;
    .pt_env 因为被 ignore 根本进不了 git diff --cached,别拿它当"已经挡住了"的证据)
  • 永不入库:.venv/、dist/、dist_packtest/、build*/、__pycache__/、.idea/、
    Excel 临时锁文件 ~$*(已在 .gitignore 覆盖)
  • core.zip / excel2mysql.zip 是历史遗留的源码副本,保持未跟踪,
    既不提交也不删除,等用户决定
  • .gitignore 里 !excel2mysql.spec / !packtest.spec 两条否定不能删:
    GitHub 的 Python 模板含 *.spec,删掉会让打包配置静默漏出仓库,别人 clone 后构建不了
  • *.bat 必须保持 CRLF(.gitattributes 已固定),改任何 .bat(三端打包入口、构建验证、对撞)后不要顺手转成 LF
  • 公开仓库:文档与注释里不出现内部数据包代号、内网地址、他人姓名等

与其他规则冲突时

  • 用户当次明确指令 > 本技能;本技能 > 工作区级同名技能(本项目自带一套,以本项目为准)
  • 不可逆操作(删文件、git reset --hard、动远端分支、改 git config)一律先问用户