一个标准的版本号必须是X.Y.Z的形式,X是主版本,Y是副版本,Z是补丁版本。.
-
X: 代表发生了不兼容的API改变
-
Y: 代表向后兼容的功能性变化
-
Z: 代表向后兼容bug fixes
即:
版本格式:主版本号.次版本号.修订号,版本号递增规则如下:
- 主版本号:当你做了不兼容的 API 修改,
- 次版本号:当你做了向下兼容的功能性新增,
- 修订号:当你做了向下兼容的问题修正。
先行版本号及版本编译信息可以加到“主版本号.次版本号.修订号”的后面,作为延伸。
语义化版本号规则:
(1)X.Y.Z - A.B.C 连字符范围
1.2.3 - 2.3.4 等价于 >=1.2.3 <=2.3.4 1.2.3 - 2 等价于 >=1.2.3 <3.0.0
(2)~1.2.3 波浪线范围
~1.2.3 等价于 >=1.2.3 <1.(2+1).0 等价于="">=1.2.3 <1.3.0
~1.2 等价于 >=1.2.0 <1.(2+1).0 等价于="">=1.2.0 <1.3.0 (Same as 1.2.x)
~1 等价于 >=1.0.0 <(1+1).0.0 等价于 >=1.0.0 <2.0.0 (Same as 1.x)
~0.2.3 等价于 >=0.2.3 <0.(2+1).0 等价于="">=0.2.3 <0.3.0
~0.2 等价于 >=0.2.0 <0.(2+1).0 等价于="">=0.2.0 <0.3.0 (Same as 0.2.x)
~0 等价于 >=0.0.0 <(0+1).0.0 等价于 >=0.0.0 <1.0.0 (Same as 0.x)
脱字符范围之后指定从左面起第一个非零位置的范围。
^1.2.3 等价于 >=1.2.3 <2.0.0
^0.2.3 等价于 >=0.2.3 <0.3.0
^0.0.3 等价于 >=0.0.3 <0.0.4,即等价于0.0.3
当然如果最后一位省略了或为通配符x,X,*,则指定前一位字符的范围,如
^1.2.x 等价于 >=1.2.0 <2.0.0
^0.0.x 等价于 >=0.0.0 <0.1.0
^0.0 等价于 >=0.0.0 <0.1.0
结论:
~x.y.z: 匹配大于 x.y.z 的 z 的最新版
^x.y.z: 匹配大于 x.y.z 的 y.z 的最新版
当 x 为 0 时,^x.y.z 等价于 ~x.y.z,即只会安装z 的最新版本;
当 x 和 y 为 0 时,^x.y.z 等价于 x.y.z,即只会安装x.y.z 版本;
为什么要使用语义化的版本控制?
这并不是一个新的或者革命性的想法。实际上,你可能已经在做一些近似的事情了。问题在于只是“近似”还不够。如果没有某个正式的规范可循,版本号对于依赖的管理并无实质意义。将上述的想法命名并给予清楚的定义,让你对软件使用者传达意向变得容易。一旦这些意向变得清楚,弹性(但又不会太弹性)的依赖规范就能达成。
举个简单的例子就可以展示语义化的版本控制如何让依赖地狱成为过去。假设有个名为“救火车”的函式库,它需要另一个名为“梯子”并已经有使用语义化版本控制的套件。当救火车创建时,梯子的版本号为 3.1.0。因为救火车使用了一些版本 3.1.0 所新增的功能, 你可以放心地指定相依于梯子的版本号大等于 3.1.0 但小于 4.0.0。这样,当梯子版本 3.1.1 和 3.2.0 发布时,你可以将直接它们纳入你的套件管理系统,因为它们能与原有相依的软件兼容。
作为一位负责任的开发者,你理当确保每次套件升级的运作与版本号的表述一致。现实世界是复杂的,我们除了提高警觉外能做的不多。你所能做的就是让语义化的版本控制为你提供一个健全的方式来发行以及升级套件,而无需推出新的相依套件,节省你的时间及烦恼。
如果你对此认同,希望立即开始使用语义化版本控制,你只需声明你的函式库正在使用它并遵循这些规则就可以了。请在你的 README 文件中保留此页连结,让别人也知道这些规则并从中受益。