使用 "5W1H" 寫出高可讀的 Git Commit Message

王仕軍發表於2017-05-09

共 1926 字,讀完需 4 分鐘。所有工程師都知道,程式碼是編寫一次,修改很多次,然後閱讀更多次,程式碼可讀性的重要程度不言而喻,但是在專案演進過程中有個很重要的記錄也是會讀很多次的,那就是 Git 的提交日誌,而提交日誌裡面資訊量最大的應該是 commit message,本文靈感來自 Linux 作者 Linus Torvalds 在 GitHub 上對 commit mesage 的吐槽

Git Log 之痛

在《The Art of Readable Code》這本經典書中,有個形象的比喻,衡量程式碼可讀性的指標是閱讀程式碼時每分鐘的 WTF 次數,而在讀 Git 提交歷史的時候,不知道你有多少次爆粗口?不相信?你現在開啟公司演進最快的專案,執行 git log,資訊量過少甚至是誤導的 commit message 非常常見,比如:

fix     => 這到底是 fix 什麼?為什麼 fix?怎麼 fix 的?
update  => 更新了什麼?是為了解決什麼問題?
test    => 這個最讓人崩潰,難道是為了測試?至於為了測試而去提交一次程式碼麼?複製程式碼

說不定,你在這種 commit message 中也貢獻了一份力量呢。

正視問題

我們先放下 Git 提交日誌來看看典型的後端日誌記錄,如下面這則 access log

remote_addr=[127.0.0.1] http_x_forward=[-] time=[19/Apr/2017:07:28:13 +0800] request=[GET /admin/edu/exam_scores/index/225 HTTP/1.1] status=[200] byte=[15745] elapsed=[0.309] refer=[http://stu.youcaiedu.com/admin/edu/contests] body=[-] ua=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36] cookie=[JSESSIONID=aaaXlJyT6Ju-K-FbLuWPv; pgv_pvi=7986424832; pgv_si=s905561088; easycms=a16pbumhusksq3vpcogcv2n715; toolbarDisplay=hide; _ga=GA1.2.1604145244.1486802034] gzip=[7.71]複製程式碼

好的 access log 包含了哪些要素呢?

  • 使用者請求的時間(time);
  • 使用者請求的地址(request)、從何而來(refer);
  • 使用者來源(remote_addr);
  • 服務端響應(status, byte, elapsed);
  • ...

回憶下小學的知識,如何準確的描述一次事件?對,就是 5W1H 法則,具體說就是誰(who)在什麼時候(when)、什麼地點(where)因為什麼(why)而做了什麼事情(what),他是怎麼做的(how),access log 是典型的事件日誌,所以 access log 的記錄完全可以參照 5W1H 方法去記錄,你後來翻看的時候也不會錯過細節。

回到正題,Git Log 本質上不也是事件日誌麼?必然是線上出了問題、產品提出了需求、工程師自己做了重構或技術改進才會導致它的變遷。如果沒有詳盡記錄每次變遷的細節,程式碼 Review 的人怎麼知道你做了什麼?上線後遇到問題怎麼去追溯?新人接手程式碼怎麼去理解?

解決問題

因為 Git 的特殊性,Git 核心已經能把 5W1H 裡面的 who、when 作為 commit 元資訊記錄下來,而研發活動的 where 明顯是不需要記錄的,真正需要工程師關注的是 what、why、how,這 3 項重要資訊的載體就是 commit message。相信讀到這裡,你已經明白我想說什麼了。

下面提出一種可以幫你寫出高可讀 commit message 的實踐方法,這個方法並非原創,最早的實踐來自於這篇文章。簡單來說就是要在 commit message 中記錄本次提交的 what、why、how,那麼怎麼把這個想法整合到你的開發工作流裡面呢?可以參考下面的步驟來完成:

1. 設定 .gitmessage 模板

這是 Git 內建就支援的,你可以為每次提交的 commit message 設定一個模板,每次提交的時候都能促使你遵循這個思考的模式去編寫 commit message,比如下面是我的模板,存放在 ~/.gitmessage

What: 簡短的描述幹了什麼

Why:

* 我為什麼要這麼做?

How:

* 我是怎麼做的?這麼做會有什麼副作用?複製程式碼

2. 讓模板生效

在全域性 Git 配置 ~/.gitconfig 中新增如下配置:

[commit]
  template = ~/.gitmessage複製程式碼

3. 擁抱新模板

配置好模板之後,你要放棄在提交時直接指定 commit message 的習慣做法,即下面這種提交方式:

git commit -m "<commit message here>"複製程式碼

因為這種提交方式是不會彈出模板來讓你填寫的,你提交的命令應該改成:

git commit複製程式碼

具體的操作過程見下面的動圖:

使用 "5W1H" 寫出高可讀的 Git Commit Message

如同阿米爾汗在給他女兒做摔跤戰術指導時說的話:拿五分很難,但不是沒有可能。習慣的養成定不容易,但是是可行的,如果你認識到這點,離習慣養成已經很近了。

4. 給用 Vim 的同學

為了更好的 commit message 閱讀者體驗,可能你需要考慮給 commit message 裡面的內容自動換行,讓內容控制在輕鬆能看到的寬度之內,使用 Vim 的同學可以在你的 ~/.vimrc 裡面增加下面的配置:

autocmd Filetype gitcommit setlocal spell textwidth=80複製程式碼

5. 最重要的是內容

寫出高可讀的 commit message 需要你對每次提交的改動做認真深入的思考,認真回答上面提到的幾個問題:

  • What: 簡短的描述這次的改動
  • Why:為什麼修改?就是要說明這次改動的必要性,可以是需求來源,任務卡的連結,或者其他相關的資料;
  • How: 做了什麼修改?需要說明的是使用了什麼方法(比如資料結構、演算法)來解決了哪個問題;

此外,還有個非常重要的點就是本次修改的副作用可能有什麼,因為工程就是不斷在做權衡,本次修改為以後留下了什麼坑?還需要什麼工作?都可以記錄在 commit message 中。

從本質上來說,上面只是你思考問題的框架和記錄內容的形式,真正重要的是你要仔細思考的那幾個問題,因為一定程度上,commit message 就是文件,活的文件,記錄了倉庫的所有變遷。

總結

怎麼讓你的程式碼可以追溯也是優秀工程師必備的素質,相信讀到這裡,你對如何寫出高可讀的 commit message 的原因、好處、方法有了清晰的認識,紙上得來終覺淺,絕知此事要躬行,接下來你就需要把這種方法運用到實際工作中,相信我,你的同事發現之後會開始感激你、效仿你。

One More Thing

本文作者王仕軍,商業轉載請聯絡作者獲得授權,非商業轉載請註明出處。如果你覺得本文對你有幫助,請點贊!如果對文中的內容有任何疑問,歡迎留言討論。想知道我接下來會寫些什麼?歡迎訂閱我的掘金專欄知乎專欄:《前端週刊:讓你在前端領域跟上時代的腳步》。

相關文章