参考文章

版本号命名策略

在软件开发中,最通用且被广泛采纳的标准是 语义化版本控制 (Semantic Versioning),简称 SemVer

它的核心理念是通过版本号的变化,清晰地传达代码的变更性质(是否有重大改动、是否有新功能、是否兼容旧版本)。

1. 标准格式:X.Y.Z

标准的语义化版本号通常由三组数字组成,格式为 主版本号.次版本号.修订号 (Major.Minor.Patch)。

  • 主版本号 (Major Version) - X
    • 何时修改: 当做了不兼容的 API 修改时。
    • 含义: 这是一个大版本更新,可能包含架构重构。升级到这个版本的用户通常需要修改自己的代码才能继续使用(即“破坏性变更”)。
    • 示例:1.0.0 升级到 2.0.0
  • 次版本号 (Minor Version) - Y
    • 何时修改: 当做了向下兼容的功能性新增时。
    • 含义: 增加了一些新功能,但并没有破坏现有的 API。旧版本的用户可以直接升级而不需要改代码。
    • 示例:1.1.0 升级到 1.2.0
  • 修订号 (Patch Version) - Z
    • 何时修改: 当做了向下兼容的问题修正 (Bug Fix) 时。
    • 含义: 仅仅是修复了 Bug,没有新功能,API 也没有变。
    • 示例:1.0.1 升级到 1.0.2

规则: 一旦主版本号(Major)升级,次版本号(Minor)和修订号(Patch)必须归零。


2. 先行版本号 (Pre-release)

在正式发布之前,添加后缀来标识开发进度。格式通常是 主.次.修-阶段标识

常见的后缀阶段如下:

阶段标识 全称 含义 稳定性
alpha Alpha 内测版。功能未开发完,Bug 较多,通常只在内部或给核心开发者测试。 🔴 极低
beta Beta 公测版。功能已基本完成,主要用于发现 Bug。UI/UX 可能还会微调。 🟡 低
rc Release Candidate 候选发布版。不再增加新功能,如果没有发现重大 Bug,它就是正式版。 🟢 高
GA / Stable General Availability 正式发布版。通常不带后缀,或者标记为 Stable。 🔵 稳定

示例演变:

  1. 1.0.0-alpha.1 (第一次内测)
  2. 1.0.0-beta.1 (开启公测)
  3. 1.0.0-rc.1 (候选发布)
  4. 1.0.0 (正式发布)

Linux内核的版本命名

虽然 Linux 内核的版本号看起来很像 SemVer(格式为 Major.Minor.Patch,例如 6.1.12),但在含义上有本质的区别。Linux 内核主要采用的是一种基于时间Linus Torvalds 个人判断的版本策略,而不是基于 API 兼容性的策略。

维度 SemVer (语义化版本) Linux 内核版本规范
主版本号 (X.y.z) 有破坏性更新时增加。 任意决定。通常是因为次版本号变得太大(”手指头数不过来了”),或者作为一个心理上的里程碑。
次版本号 (x.Y.z) 向后兼容的新功能 新内核发布。包含新特性、驱动和改进。这是内核开发的主节奏(约 9-10 周一次)。
修订号 (x.y.Z) 向后兼容的 Bug 修复 稳定版/LTS 更新。仅包含 Bug 修复和安全补丁,不包含新功能。
兼容性承诺 通过版本号明确告知是否兼容。 “永远不要破坏用户空间” (Never Break Userspace)。无论版本号如何变,旧程序都应该能在新内核上运行。

在参考文章中,Greg K-H 将现代版本号定义为三个部分,例如 6.1.12

A. Major (主版本号,其中的6)

  • 含义: 没有任何特殊的技术含义。
  • 何时增加: 纯粹是因为后面的数字(Minor)变得太大了,Linus 觉得看着累或者手指头数不过来了,就进一位。它不代表重大的架构重写或不兼容变更。

在 Linux 2.6 时代之后,主版本号的升级不再代表架构上的巨变。

  • 3.0 的由来:Linus 觉得 2.6.39 后面的数字太长了,所以升到了 3.0
  • 4.0 的由来:Linus 发起了一个社区投票,大家都想看大数字变动,或者是觉得 3.19 后面接 4.0 比较好看。
  • 5.0 的由来:同样是因为 4.x 的数字数到了 4.20,手指脚趾不够用了。

B. Minor (次版本号,其中的1)

  • 含义: 代表一个新的内核发布分支(Kernel Branch)。
  • 发布节奏: 基于时间驱动,大约每 10周 发布一次。
  • 规则: 只要是 Linus 发布的 Major.Minor(例如 5.2),它就是稳定的。

C. Stable (稳定修订号,其中的12)

  • 含义: 针对该分支的 Bug 修复更新。

  • 来源: 所有的修复必须先进入 Linus 的主线(Mainline),然后才能被“向后移植”(Backport)到这些稳定版中。

  • 例子: 5.2.0 -> 5.2.1 -> 5.2.2… 这些版本只修 Bug,不加新功能。

3. 如何理解“分支”与“生命周期”

文章中用图解逻辑解释了 .y 的概念(即 5.4.y 代表 5.4 的整个稳定分支):

  • 普通分支: 大多数分支(如 5.2, 5.3)只存活几个月,直到下一个版本稳定下来。
  • 长期支持 (LTS): 每年通常会选这年的最后一个版本作为 LTS(Longterm),维护至少 2 年。

4. 重要的“警告”:版本号比较的陷阱

Greg K-H 特别指出了一个常见的错误认知

  • 错误想法: “版本号数字大的那个,一定包含数字小的那个版本里的所有补丁。”
  • 实际情况: 你不能简单地跨分支比较。
    • 例如:一个在 5.4.200 (LTS) 中修复的安全漏洞,可能在 5.5.0 (早期普通版) 发布时还没来得及合入。
    • 结论: 必须把每个 Major.Minor 看作一个独立的“树(Tree)”来追踪。

总结:

通过对比 SemVer 和 Linux 内核的版本策略,我们可以发现,版本号不仅仅是一串数字,它本质上是开发者与用户之间的一份归约。

  • SemVer 的契约是“兼容性”:它服务于包管理器和依赖系统(如 npm, Cargo, Maven)。它的目的是告诉计算机:“我可以安全地自动升级这个库吗?”
  • Linux 的契约是“稳定性与演进”:它服务于操作系统维护者和最终用户。它的目的是告诉人类:“这是最新的技术成果(Mainline),还是经过长期打磨的坚实后盾(LTS)?”

对于开发者而言,理解这一点至关重要:

  1. 在设计自己的软件时:尽量遵循 SemVer,因为它可以显著降低下游用户的维护成本,避免“依赖地狱”。
  2. 在维护 Linux 系统时:不要对主版本号(Major)的变动感到恐慌,也不要盲目追求最新的次版本号(Minor)。真正值得你关注的,是那个代表着安全补丁和 Bug 修复的修订号(Patch/Stable)。

正如 Linus Torvalds 所坚持的那样,Linux 内核最核心的规则从来不是版本号怎么写,而是那句刻在开发者心中的铁律——“永远不要破坏用户空间” (WE DO NOT BREAK USERSPACE!)。这才是比任何数字都更值得信赖的承诺。