# 語義化版本
### 摘要
版本格式:主版本號.次版本號.修訂號,版本號遞增規則如下:
- 主版本號:當你做了不兼容的API 修改。
- 次版本號:當你做了向下兼容的功能性新增。
- 修訂號:當你做了向下兼容的問題修正。
先行版本號及版本編譯信息可以加到“主版本號.次版本號.修訂號”的后面,作為延伸。
### 簡介
在軟件管理的領域里存在著被稱作“依賴地獄”的死亡之谷,系統規模越大,加入的套件越多,你就越有可能在未來的某一天發現自己已深陷絕望之中。
在依賴高的系統中發布新版本套件可能很快會成為惡夢。如果依賴關系過高,可能面臨版本控制被鎖死的風險(必須對每一個相依套件改版才能完成某次升級)。而如果依賴關系過于松散,又將無法避免版本的混亂(假設兼容于未來的多個版本已超出了合理數量)。當你專案的進展因為版本相依被鎖死或版本混亂變得不夠簡便和可靠,就意味著你正處于依賴地獄之中。
作為這個問題的解決方案之一,我提議用一組簡單的規則及條件來約束版本號的配置和增長。這些規則是根據(但不局限于)已經被各種封閉、開放源碼軟件所廣泛使用的慣例所設計。為了讓這套理論運作,你必須先有定義好的公共API。這可以透過文件定義或代碼強制要求來實現。無論如何,這套API 的清楚明了是十分重要的。一旦你定義了公共API,你就可以透過修改相應的版本號來向大家說明你的修改。考慮使用這樣的版本號格式:XYZ (主版本號.次版本號.修訂號)修復問題但不影響API 時,遞增修訂號;API 保持向下兼容的新增及修改時,遞增次版本號;進行不向下兼容的修改時,遞增主版本號。
我稱這套系統為“語義化的版本控制”,在這套約定下,版本號及其更新方式包含了相鄰版本間的底層代碼和修改內容的信息。
### 語義化版本控制規范(SemVer)
以下關鍵詞MUST、MUST NOT、REQUIRED、SHALL、SHALL NOT、SHOULD、SHOULD NOT、 RECOMMENDED、MAY、OPTIONAL 依照RFC 2119 的敘述解讀。(譯注:為了保持語句順暢, 以下文件遇到的關鍵詞將依照整句語義進行翻譯,在此先不進行個別翻譯。)
1. 使用語義化版本控制的軟件“必須MUST”定義公共API。該API可以在代碼中被定義或出現于嚴謹的文件內。無論何種形式都應該力求精確且完整。
1. 標準的版本號“必須MUST”采用XYZ的格式, 其中X、Y和Z為非負的整數,且“禁止MUST NOT”在數字前方補零。X是主版本號、Y是次版本號、而Z為修訂號。每個元素“必須MUST”以數值來遞增。例如:1.9.1 -> 1.10.0 -> 1.11.0。
1. 標記版本號的軟件發行后,“禁止MUST NOT”改變該版本軟件的內容。任何修改都“必須MUST”以新版本發行。
1. 主版本號為零(0.yz)的軟件處于開發初始階段,一切都可能隨時被改變。這樣的公共API 不應該被視為穩定版。
1. 1.0.0 的版本號用于界定公共API 的形成。這一版本之后所有的版本號更新都基于公共API 及其修改內容。
1. 修訂號Z(xyZ | x > 0)“必須MUST”在只做了向下兼容的修正時才遞增。這里的修正指的是針對不正確結果而進行的內部修改。
1. 次版本號Y(xYz | x > 0)“必須MUST”在有向下兼容的新功能出現時遞增。在任何公共API的功能被標記為棄用時也“必須MUST”遞增。也“可以MAY”在內部程序有大量新功能或改進被加入時遞增,其中“可以MAY”包括修訂級別的改變。每當次版本號遞增時,修訂號“必須MUST”歸零。
1. 主版本號X(Xyz | X > 0)“必須MUST”在有任何不兼容的修改被加入公共API時遞增。其中“可以MAY”包括次版本號及修訂級別的改變。每當主版本號遞增時,次版本號和修訂號“必須MUST”歸零。
1. 先行版本號“可以MAY”被標注在修訂版之后,先加上一個連接號再加上一連串以句點分隔的標識符號來修飾。標識符號“必須MUST”由ASCII碼的英數字和連接號[0-9A-Za-z-]組成,且“禁止MUST NOT”留白。數字型的標識符號“禁止MUST NOT”在前方補零。先行版的優先級低于相關聯的標準版本。被標上先行版本號則表示這個版本并非穩定而且可能無法達到兼容的需求。范例:1.0.0-alpha、1.0.0-alpha.1、 1.0.0-0.3.7、1.0.0-x.7.z.92。
1. 版本編譯信息“可以MAY”被標注在修訂版或先行版本號之后,先加上一個加號再加上一連串以句點分隔的標識符號來修飾。標識符號“必須MUST”由ASCII的英數字和連接號[0-9A-Za-z-]組成,且“禁止MUST NOT”留白。當判斷版本的優先層級時,版本編譯信息“可SHOULD”被忽略。因此當兩個版本只有在版本編譯信息有差別時,屬于相同的優先層級。范例:1.0.0-alpha+001、1.0.0+20130313144700、 1.0.0-beta+exp.sha.5114f85。
1. 版本的優先層級指的是不同版本在排序時如何比較。判斷優先層級時,“必須MUST”把版本依序拆分為主版本號、次版本號、修訂號及先行版本號后進行比較(版本編譯信息不在這份比較的列表中)。由左到右依序比較每個標識符號,第一個差異值用來決定優先層級:主版本號、次版本號及修訂號以數值比較,例如1.0.0 < 2.0.0 < 2.1.0 < 2.1.1。當主版本號、次版本號及修訂號都相同時,改以優先層級比較低的先行版本號決定。例如:1.0.0-alpha < 1.0.0。有相同主版本號、次版本號及修訂號的兩個先行版本號,其優先層級“必須MUST”透過由左到右的每個被句點分隔的標識符號來比較,直到找到一個差異值后決定:只有數字的標識符號以數值高低比較,有字母或連接號時則逐字以ASCII的排序來比較。數字的標識符號比非數字的標識符號優先層級低。若開頭的標識符號都相同時,欄 位比較多的先行版本號優先層級比較高。范例:1.0.0-alpha < 1.0.0-alpha.1 < 1.0.0-alpha.beta < 1.0.0-beta < 1.0.0-beta.2 < 1.0.0-beta.11 < 1.0.0- rc.1 < 1.0.0。
### 為什么要使用語義化的版本控制?
這并不是一個新的或者革命性的想法。實際上,你可能已經在做一些近似的事情了。問題在于只是“近似”還不夠。如果沒有某個正式的規范可循,版本號對于依賴的管理并無實質意義。將上述的想法命名并給予清楚的定義,讓你對軟件使用者傳達意向變得容易。一旦這些意向變得清楚,彈性(但又不會太彈性)的依賴規范就能達成。
舉個簡單的例子就可以展示語義化的版本控制如何讓依賴地獄成為過去。假設有個名為“救火車”的函式庫,它需要另一個名為“梯子”并已經有使用語義化版本控制的套件。當救火車創建時,梯子的版本號為3.1.0。因為救火車使用了一些版本3.1.0 所新增的功能, 你可以放心地指定相依于梯子的版本號大等于3.1.0 但小于4.0.0。這樣,當梯子版本3.1.1 和3.2.0 發布時,你可以將直接它們納入你的套件管理系統,因為它們能與原有相依的軟件兼容。
作為一位負責任的開發者,你理當確保每次套件升級的運作與版本號的表述一致。現實世界是復雜的,我們除了提高警覺外能做的不多。你所能做的就是讓語義化的版本控制為你提供一個健全的方式來發行以及升級套件,而無需推出新的相依套件,節省你的時間及煩惱。
如果你對此認同,希望立即開始使用語義化版本控制,你只需聲明你的函式庫正在使用它并遵循這些規則就可以了。請在你的README 文件中保留此頁連結,讓別人也知道這些規則并從中受益。
### 參考資料
- [Semantic Versioning 2.0.0](http://semver.org/)
- 介紹
- 程序員基礎知識
- 字符編碼
- 技術名詞
- 語義化版本
- 命名規范
- 書寫文檔
- 開源協議
- 目錄結構
- 正則表達式
- 平凡之路
- 數據結構與算法
- 堆和棧
- 浮點數類型
- XML和JSON
- 算法學習之路
- 排序算法
- 代碼架構
- 設計模式
- 常用的Javascript設計模式
- 面向對象編程
- 繼承
- 多態
- 封裝
- 面向接口編程
- 代碼評審
- 六種量化你代碼的方式
- 程序員必備的代碼審查(Code Review)清單
- 服務器部署
- AWS簡介
- 網絡知識
- HTTPS, SPDY和 HTTP/2性能的簡單對比
- HTTP狀態碼
- 懂點設計
- 佳作賞析
- 無縫平鋪
- Sketch學習
- 設計與實現的平衡
- 寫點東西
- 使用gitbook
- 合格的PM
- 一個好的產品經理
- 產品經理的技能
- 團隊合作
- 關于招聘
- 培訓新人
- 領導能力
- 獲取知識
- MOOC
- Podcasts
- 英語學習
- 設計學習
- 前端學習
- iOS學習
- 游戲開發
- 關注健康
- 過勞檢測
- 關于睡眠
- 提升效率
- 學會閱讀
- 學會提問
- 善用搜索
- 學會寫作
- 時間管理
- 知識管理
- 文件管理
- 密碼管理
- 制作視頻
- 制作PPT
- 論音樂對效率的影響
- 程序員效率指南
- SOHO
- 創業資源
- Hacker
- 保護隱私
- 關于工作
- 找工作前需要思考的問題
- 原則與技巧
- 關于簡歷
- 其他方面
- 硬件相關
- 常用軟件
- Windows
- 硬件配置
- 系統安裝
- 常用軟件
- Mac
- 通用設置
- 權限問題
- alias設置
- 常用軟件
- 開發環境
- 快捷鍵設置
- 常用終端命令
- dotfiles
- Android
- 常用軟件
- 如何登錄美國區GooglePlay
- 開發工具
- git
- EditorConfig
- node
- shadowsocks
- ST3--Windows篇
- ST3--Mac篇
- gulp
- 字體的選擇
- Emacs
- WebStorm
- tmux
- Sketch
- Sketch中文學習資料
- Trello
- 使用Trello管理項目的經驗
- git進階
- 15分鐘學會使用Git和遠程代碼庫
- GitHub秘籍
- JetBrains
- IDE設置
- 附錄
- 計算機科學與技術
- 網站
- 書籍
- 工具