QMK Firmware Breaking Changes 流程:当你的 Pull Request 被标记为破坏性变更时该如何应对
2026/9/13 17:18:01 网站建设 项目流程

QMK Firmware Breaking Changes 流程:当你的 Pull Request 被标记为破坏性变更时该如何应对

【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware

QMK 以"更新代码树不会弄坏用户现有键位图(keymap)"为底线,对破坏性变更(Breaking Change)实施了一套严格的准入与合并流程。本文围绕官方文档中"我的 PR 被标记为破坏性变更"这一场景展开:先讲清楚什么样的改动会被打上破坏性变更标签,再给出拆分 PR、补文档、寻求帮助三类实操建议,并结合仓库内的流程文档与真实 Changelog,深入解析 3 个月一期的developmaster合并机制、各阶段检查清单与 Git 操作命令,帮助你既顺利完成贡献,又理解维护者视角下的风险控制逻辑。

什么改动会被标记为 Breaking Change

QMK 对破坏性变更的定义是:任何以不兼容或潜在危险的方式改变 QMK 行为的变更,此外还包括仓库内键盘文件的移动。QMK 刻意限制这类变更的合入节奏,让用户可以确信更新 QMK 代码树不会弄坏自己的键位图(见 Breaking Changes 文档)。

在实践层面,QMK 每 3 个月将develop分支合并回master一次,这个窗口期就是"破坏性变更期":在此期间会合并那些以危险或出乎意料方式改变 QMK 的 PR,并预留一段内置的测试缓冲,以确认由变更引发的问题足够少或不可预测(见 Breaking Changes 文档)。

当你提交了一个 PR,QMK 成员可能会回复说你的提交属于破坏性变更——这意味着在他们看来,你的改动对 QMK 本身或其用户有更大的影响面。根据 PR 被标记后的说明文档,常见触发原因有五类:

  1. 对用户键位图的编辑(Edits to User Keymaps)用户可能把自己提交的 keymap 捐献给 QMK 仓库,一段时间后再次发起 PR 更新它,却发现因为该 keymap 已经在qmk/qmk_firmware仓库内被他人编辑过而无法合并。由于并非所有用户都熟练使用 Git/GitHub,这类用户往往无法自行解决冲突。

  2. 改变预期行为(Changes to Expected Behavior)改变 QMK 既有功能的行为,可能让刷入新固件的用户误以为硬件或 QMK 坏了——他们发现自己的行为变了,却找不到恢复原行为的手段。

  3. 要求用户采取行动的变更(Changes Requiring User Action)变更可能要求用户做出额外操作,例如升级工具链,或在 Git 层面执行某些动作。

  4. 需要加强审查的变更(Changes Necessitating Increased Scrutiny)某些提交对 QMK 项目本身有影响,例如版权/许可问题、编码规范问题、大规模功能重构、需要社区更广泛测试的"高风险"变更,或其他性质的敏感改动。

  5. 需要向最终用户传达信息的变更(Changes Requiring Communication to End Users)包括未来弃用的预警、过时用法的提示,以及其他需要传达但不属于以上任何一类的内容。

PR 被标记后,你可以做什么

被标记并不意味着 PR 被拒绝。说明文档给出了三条具体建议,都是围绕"降低合并风险、加快审查"展开的。

1. 考虑把 PR 拆分

如果你在贡献核心代码,而它需要走破坏性变更流程的唯一原因是"要顺手更新 keymap 以适配你的改动",那么请考虑能否以"旧 keymap 继续可用"的方式提交你的功能。然后另开一个独立 PR,走破坏性变更流程去移除旧代码。

这个策略的本质是把"行为不变的增量"与"必须变更行为的清理"解耦:前者可以随常规流程快速合入,后者按 3 个月节奏统一进入测试窗口。这与后文会讲的接受标准中"PR 越简单,维护者越容易审查"的原则一脉相承。

2. 把你的变更写清楚

让审查者理解你提交的目的、可能带来的影响以及用户需要采取的行动,可以显著简化审查过程。Changelog 文件在多数情况下足以承担这个职责,但更广泛的变更可能需要超出 Changelog 粒度的细节。

在 PR 下主动评论、及时回应提问、评论与修改要求,是被明确"非常欢迎"的做法。

3. 寻求帮助

如果 PR 被标记这件事让你措手不及,或者你感到不知所措,直接说出来:在 PR 下留言,或联系 QMK 团队(官方文档中给出的渠道是 Discord)。流程上不存在"必须独自扛下来"的隐含要求。

Breaking Changes 周期全景:3 个月一次的 develop → master 合并

理解自己被标记的 PR 会流向哪里,需要先看清整个周期的时间线。根据 Breaking Changes 文档 的当前内容,下一个 Breaking Change 排期为 2026 年 8 月 30 日,重要节点如下:

  • 2025 年 5 月 31 日 -develop打上新版本发布标签;此后每次推送到master都由 GitHub Actions 自动合并回develop
  • 2026 年 8 月 2 日 -develop停止接收新 PR;同时发起测试者征集(call for testers)。
  • 2026 年 8 月 16 日 - 合并截止日——此后再进入develop的只有 bugfix。
  • 2026 年 8 月 23 日 -develop锁定,只合并关键 bugfix PR。
  • 2026 年 8 月 28 日 -master锁定,不再合并 PR。
  • 2026 年 8 月 30 日 - 将develop合并进mastermaster随即解锁,恢复 PR 合并。

(以上日期以仓库当前文档快照为准;每个周期开始前维护者都会更新文档中的日期。)

变更如何被收集与判定

develop关闭前提交并被 QMK Collaborators 接受的破坏性变更,才会进入本轮;develop关闭后的新提交将被推迟到下一个周期。仓库文档中提到的两个标签机制值得注意:

  • core标签:每当 PR 被创建或更新时自动检查,若包含对 QMK 核心区域的改动则自动打标。带有该标签不代表保证会在当前周期合并,且在develop关闭前仍可能加入新的变更,处理冲突一般是提交者的责任。
  • breaking_change_YYYYqN标签:由 QMK Collaborators 使用,表示该 PR 是本轮的强候选项,应优先审查。

接受标准(来自 Breaking Changes 文档):

  • PR 是完整且可直接合并的状态;
  • GitHub 检查项尽可能全绿。"红"的检查在以下情况可被维护者忽略:被标记的问题与 PR 提出的改动无关(例如修改已有文件不需要补 license 头才能通过 lint);与 PR 功能无直接关系的改动,宁可不要顺手做。

强烈建议:在<qmk_firmware>/docs/ChangeLog/<日期>下提交一个描述变更的 ChangeLog 文件,Markdown 格式,文件名形如PR12345.md(数字替换为你的 PR ID);并强烈建议该 ChangeLog 文档内容与 PR 描述保持一致,以保证可追溯性。

一个简单的经验法则同样来自该文档:PR 越简单,维护者越容易审查,合入速度越快。大 PR 需要大量注意力、重构和多轮来回——而其他 PR 在持续合入,未合并的大 PR 产生冲突的概率也随之升高。

周期各阶段的操作检查清单

BREAKING CHANGES 文档 中记录了维护者执行流程时使用的各阶段清单。以下摘录关键的运维动作与合并日(Day Of Merge)的完整 Git 命令,便于理解每一阶段仓库的状态。

合并前 4 周

  • develop关闭新 PR,只允许合并针对现有 PR 的修复;
  • 在 Discord#qmk_firmware频道向@Breaking Changes Updates发消息,宣告本轮面向develop的功能性 PR 提交截止日。

合并前 2 周

  • develop停止合并现有 PR,只接受针对已合并内容的 bugfix;
  • 再次发布测试者征集公告,宣告"功能性 PR 合并截止"。

合并前 1 周

  • develop只接受关键 bugfix;
  • 预告master将在"合并日前 2 天"至"合并日"期间关闭。

合并前 2 天

  • master关闭 PR 合并;
  • 公告 master 将锁定数日,以便准备从develop合并最新一批变更。

合并日(Day Of Merge)

这是整个周期操作密度最高的一天,文档中给出的 Git 命令如下(在qmk_firmware仓库内执行):

# 先在 develop 上完成合并点提交 git checkout develop git pull --ff-only # 编辑 readme.md:移除关于 develop 分支的说明 # 将 ChangeLog 汇总为一个文件 git commit -m 'Merge point for <DATE> Breaking Change' git push upstream develop

随后在 GitHub Actions 层面为develop创建一个 PR,并且先关闭仓库的"Automatically delete head branches"选项——需与 @qmk/directors 确认完成后再继续。

# 切回 master 并执行非 fast-forward 合并 git checkout master git pull --ff-only git merge --no-ff develop git tag <next_version> # 防止 breakpoint tag 干扰版本号递增 git push upstream <next_version> git push upstream master

合并后的收尾操作

合并完成不是周期的终点。文档 的 Post-merge operations 部分定义了紧接着的两类工作。

重建新的 develop 分支

develop合入master后立即执行:

git checkout master git pull --ff-only git checkout develop git pull --ff-only git merge --no-ff master # 编辑 readme.md:在顶部加醒目提示,说明这是测试分支,并附上破坏性变更文档链接 git commit -m 'Branch point for <DATE> Breaking Change' git tag breakpoint_<YYYY>_<MM>_<DD> git push upstream breakpoint_<YYYY>_<MM>_<DD> git push upstream develop

其中breakpoint_<YYYY>_<MM>_<DD>标签的作用与合并日打<next_version>标签类似:标记分叉点,避免后续版本号递增逻辑被歧义标签干扰。

校验 lib 下子模块与 QMK fork 的一致性

lib下的所有子模块需要与对应的 QMK fork 逐一比对,因为 SHA1 不匹配会导致 Configurator 无法工作:

# 查看各子模块当前指向的提交 git submodule foreach git log -n1

以 ChibiOS 为例:将其输出的 commit hash 与 qmk fork 的qmk-master分支比对,若不一致则需要在子模块仓库内执行:

cd lib/chibios git fetch --all git checkout qmk-master git reset --hard <commit hash> git push origin qmk-master --force-with-lease

可选地,维护者还会按 ChibiOS 升级说明 在develop上更新 ChibiOS 与 ChibiOS-Contrib。最后,在 Discord 公告masterdevelop均已解锁,新一批变更对所有人可用;并为下一个周期更新docs/breaking_changes.md中的日期、在 Discord 创建 5 个关键事件(功能 PR 提交截止、功能 PR 合并截止、develop 关闭、master 关闭、develop 合入 master)。

弃用策略:破坏性变更中的"预告期"

破坏性变更并不都是"一刀切"。QMK 有明确的弃用与移除策略(见 Feature support policies):

  • 大型功能或整个子系统的弃用,至少会在移除前一个破坏性变更周期(3 个月)先在develop分支上通告;影响面更大的功能,预告期可能更长,由 QMK 团队酌情决定。
  • 较小的功能可能在单个周期内被移除,通常依据其在仓库内的使用程度决定——使用率极低的功能随时可能在develop上被选中移除。
  • 每次从develop合并到master的破坏性变更都会附带 Changelog 文档,计划内与已完成的弃用都会在其中通告;并且尽可能在编译仍在使用已弃用特性的固件时发出编译期警告。

一个真实的例子来自 2026 年 5 月 31 日 Changelog:该版本移除了已弃用的isLeftHand,要求用户迁移到split_util.h中的is_keyboard_left()

oled_rotation_t oled_init_user(oled_rotation_t rotation) { - return isLeftHand ? OLED_ROTATION_180 : OLED_ROTATION_0; + return is_keyboard_left() ? OLED_ROTATION_180 : OLED_ROTATION_0; }

同一份 Changelog 还记录了usb.force_nkro/FORCE_NKRO的移除(原假设"只有 USB 能做 NKRO"被拆掉后,开机强制 NKRO 会产生与NK_TOGG等 NKRO 键码行为不一致的用户困惑)。迁移方式为在新默认配置体系中开启 NKRO——例如在keyboard.jsonkeymap.json中:

{ "host": { "default": { "nkro": true } } }

或在config.h中:

#pragma once #define NKRO_DEFAULT_ON true

这类"先弃用、给预告期、再在某个周期移除并给出迁移示例"的模式,正是第五类触发条件(需要向最终用户传达信息)在仓库中的具体落地方式。

历史 Breaking Changes 一览

每个合并周期都会留下一份 Changelog,完整索引见 Past Breaking Changes。从 2019 年 8 月 30 日(版本 0.7.0)到 2026 年 5 月 31 日(版本 0.33.0),周期基本保持 3 个月一次的节奏,对应文件依次为 docs/ChangeLog/20190830.md 至 docs/ChangeLog/20260531.md。这些文件既是用户升级前的行为差异对照表,也是维护者"记录影响面"的范本:按 Core / CLI / Submodule updates / Keyboards / Others / Bugs 分区列出全部变更条目并附 PR 编号,值得在提交自己的破坏性变更 Changelog 时参照其结构。

小结

把 PR 被标记为破坏性变更视为一次"风险分级"而不是拒绝信号:先判断它命中五类触发条件中的哪一类,再决定是拆分 PR(让旧 keymap 继续工作)、补充影响面说明与 ChangeLog,还是直接向团队求助。与此同时,QMK 用"3 个月周期 + 明确的关闭/锁定时间线 + 合并日固定 Git 流程 + 合并后子模块一致性校验 + Changelog 归档"这套机制,把对用户键位图的冲击控制在一个可预期、可测试的窗口内——理解这套机制,是提交任何触及 QMK 核心行为变更前最划算的准备。

延伸阅读

  • PR 被标记后的说明(本文主体文档)
  • Breaking Changes 流程与时间线
  • 历史 Breaking Changes 索引
  • 弃用与移除策略
  • 2026 年 5 月 31 日 Changelog 实例

【免费下载链接】qmk_firmwareOpen-source keyboard firmware for Atmel AVR and Arm USB families项目地址: https://gitcode.com/GitHub_Trending/qm/qmk_firmware

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询