---
title: 如何維護更新日誌
description: 別讓你的更新日誌成為 git log 的雙胞胎
language: zh-TW
version: 1.0.0
---
.header
.title
%h1= current_page.data.title
%h2= current_page.data.description
= link_to data.links.changelog do
Version
%strong= current_page.metadata[:page][:version]
%pre.changelog{ lang: "en" }= File.read("CHANGELOG.md")
.answers
%h3#what
%a.anchor{ href: "#what", aria_hidden: "true" }
更新日誌是什麼?
%p
更新日誌(Changelog)是說明專案在開發過程中,版本之間的差異紀錄,由開發人員由新而舊撰寫。
%h3#why
%a.anchor{ href: "#why", aria_hidden: "true" }
為什麼需要提供更新日誌?
%p
為了讓使用者和開發人員更簡單明確地了解各個版本之間有著哪些改動。
%h3#who
%a.anchor{ href: "#who", aria_hidden: "true" }
哪些人需要更新日誌?
%p
大家都需要更新日誌。
%p
無論是開發人員或是使用者,都會在意軟體包含了什麼東西。
當軟體更新了,大家都想知道改了些什麼以及為什麼要改。
.good-practices
%h3#how
%a.anchor{ href: "#how", aria_hidden: "true" }
如何寫出高品質的日誌?
%h4#principles
%a.anchor{ href: "#principles", aria_hidden: "true" }
撰寫原則
%ul
%li
更新日誌是寫給「人」看的,不是機器。
%li
每個版本都應該有獨立的進入點。
%li
相同類型的改動應該被分類在同一組。
%li
版本與章節應「可連結化」。
%li
新版本總是寫在最前面。
%li
每個版本都應該註記發佈日期。
%li
版本命名應遵守#{link_to "語意化版本", data.links.semver}格式。
%a.anchor{ href: "#types", aria_hidden: "true" }
%h4#types 改動類型
%ul
%li
%code Added
:當增加了新功能。
%li
%code Changed
:當更動了既有的功能。
%li
%code Deprecated
:當功能將在近期被移除。
%li
%code Removed
:當移除了現有的功能。
%li
%code Fixed
:當修復了某些錯誤。
%li
%code Security
:當增進了安全性漏洞。
.effort
%h3#effort
%a.anchor{ href: "#effort", aria_hidden: "true" }
如何提升維護「更新日誌」的效率?
%p
在日誌上方使用 Unreleased
區塊記錄即將發佈的更新內容。
%p 這麼做能夠:
%ul
%li
讓大家知道在未來的版本中可能會有哪些改動。
%li
發佈新版本時,直接將 Unreleased
移到新版本的區塊就完成了 ヾ(*´ω`*)ノ
.bad-practices
%h3#bad-practices
%a.anchor{ href: "#bad-practices", aria_hidden: "true" }
不就只是個日記而已嗎?難道可以把日誌得很糟嗎?
%p 當然,下面有些糟糕的範例:
%h4#log-diffs
%a.anchor{ href: "#log-diffs", aria_hidden: "true" }
🚫 直接複製 git log 到更新日誌
%p
直接把 git log 複製一份成更新日誌絕對不是個好主意。
%p
git log 充滿了各種瑣碎的訊息,像 merge commits、亂七八糟的提交訊息或是文件更新等。
%p
Commits 的目的應該是記錄原始碼演進的過程,有些專案會清理 commits,但有些不會。
%p
更新日誌的目的則是記錄那些值得一提的改動,經常涵蓋多個 commits,最終目的仍然是讓看的人一目了然。
%h4#ignoring-deprecations
%a.anchor{ href: "#ignoring-deprecations", aria_hidden: "true" }
🚫 忽略 Deprecations
%p
當使用者升級版本時,他應該要能預先知道哪些環節可能會出問題,然而,在理想的狀況下,應該讓使用者有空間能預先升級即將被棄用的功能,替換掉棄用功能之後,再升級至棄用功能被真正移除的版本。
%p
即使不這麼做,也要在更新日誌中列出棄用的、移除的或是任何可能導致程式碼失效的重大改動。
%h4#confusing-dates
%a.anchor{ href: "#confusing-dates", aria_hidden: "true" }
🚫 容易混淆的日期格式
%p
在世界的每個角落,不同區域有著不同的時間格式,找到讓大家都滿意的日期格式不是件簡單的事。使用像
2017-07-17
的格式能清楚傳達日期,而且不易與其他日期格式混淆,同時也遵守
#{link_to "ISO 標準", data.links.isodate},因此推薦使用像這樣的日期格式。
%aside
其實還有許多應該避免的。大家可以透過
= link_to "Issue", data.links.issue
或是 Pull Request 協助蒐集 ฅ' ω 'ฅ
.frequently-asked-questions
%h3#frequently-asked-questions
%a.anchor{ href: "#frequently-asked-questions", aria_hidden: "true" }
常見問題
%h4#standard
%a.anchor{ href: "#standard", aria_hidden: "true" }
有沒有標準格式可以參考呢?
%p
並沒有。雖然有 #{link_to "GNU 更新日誌指南", data.links.gnu} 以及只有兩段長的
#{link_to "GNU - The NEWS File 指南", data.links.gnunews}(括弧笑),但這些並不足以稱為「標準」。
%p
這項專案的宗旨在於提供一個
#{link_to "更好的更新日誌範例", data.links.changelog},源於觀察開源社群中優秀的實際案例,把它們蒐集在一起。
%p
歡迎各位#{link_to "提供", data.links.issue}有建設性的建議和批評。
%h4#filename
%a.anchor{ href: "#filename", aria_hidden: "true" }
更新日誌的檔案名稱應該是?
%p
通常使用 CHANGELOG.md
。也有用
HISTORY
、NEWS
、或是 RELEASES
的例子。
%p
或許你認為取什麼名字並不是件多麼重要的事,但為什麼要讓只是想看日誌的使用者不容易找到它呢?
%h4#github-releases
%a.anchor{ href: "#github-releases", aria_hidden: "true" }
那麼 GitHub Releases 呢?
%p
這是個好問題。#{link_to "GitHub Releases", data.links.github_releases}
能手動在簡單的 git tag(如
v1.0.0
) 上附加豐富的版本資訊,也能把附帶的 tag
messages 轉換成漂亮的日誌格式。
%p
GitHub Releases 產生的日誌只能在 GitHub 上瀏覽,雖然 GitHub Releases
能做出接近本專案範例的日誌格式,但這會增加些許與 GitHub 的相依性。
%p
現行的 GitHub Releases
畢竟不像典型的大寫文件(README
、CONTRIBUTING
之類的),按理說會增加使用者找到的難度。另外還有個小問題,目前 GitHub
Releases 頁面上並沒有提供兩版版本之間 commit logs 的連結。
%h4#automatic
%a.anchor{ href: "#automatic", aria_hidden: "true" }
更新日誌能被自動生成嗎?
%p
非常困難,各式各樣的提交訊息和檔案名稱難以完全掌握。
%p
另外,有些開源專案使用由 Gemnasium
團隊開發的 #{link_to "Vandamme", data.links.vandamme}
轉換更新日誌,或許可以當作參考。
%h4#yanked
%a.anchor{ href: "#yanked", aria_hidden: "true" }
那麼被撤下的版本呢?
%p
因為重大漏洞或安全性問題而被撤下(unpublished)的版本通常不會出現在日誌裡,但建議仍然記錄下來。你可以這樣記錄它們:
%p ## [0.0.5] - 2014-12-13 [YANKED]
%p
其中 [YANKED]
標記應該和原因顯眼地標示在一起,讓使用者注意到它是最重要的事。此外,用中括弧能讓轉換用的程式更容易辨認它們。
%h4#rewrite
%a.anchor{ href: "#rewrite", aria_hidden: "true" }
可以更改過去版本的日誌內容嗎?
%p
當然可以,總是會有好的原因來改善以往寫下的日誌。我也時常發 pull request
給更新日誌不齊全的開源專案。
%p
偶爾會發現自己遺漏了某項重大更新的紀錄,很明顯你應該補齊它們。
%h4#contribute
%a.anchor{ href: "#contribute", aria_hidden: "true" }
我能做些什麼嗎?
%p
這份文件並不是《真理》,而是我經過深思熟慮、遵循蒐集到的資訊和範例之後提出的建議。
%p
源於我期望社群能達到共識,我相信討論的過程與結果一樣重要。
%p
所以,#{link_to "加入我們", data.links.repo}吧 ٩(。・ω・。)و
.press
%h3 訪談
%p
我在 #{link_to "The Changelog podcast", data.links.thechangelog} 上講述了為什麼維護者與協作者應該在意更新日誌,以及建立這項專案背後的契機。