版本控制系統是除錯的時光機#

許多 bug 都與軟體變更有關。版本控制系統(如 Git、Mercurial、Subversion)讓你能回溯歷史,找出 bug 何時被引入、由誰引入、為什麼引入。

要充分利用版本控制進行除錯,你必須養成良好的提交習慣:每次變更都是獨立的 commit,附帶有意義的 commit message,並連結到對應的 issue。

常用的版本控制除錯技巧#

檢視變更歷史#

# 查看整體提交歷史
git log

# 查看特定檔案的變更歷史
git log path/to/myfile.js

# 查看每一行程式碼的最後修改者與修改時間
git blame path/to/myfile.js

git blame 加上 -C-M 選項可以追蹤在檔案內或跨檔案移動的程式碼。

搜尋已刪除的程式碼#

如果與問題相關的程式碼已經不存在了,可以在所有歷史版本中搜尋:

git rev-list --all | xargs git grep extinctMethodName

查看特定版本之後的變更#

# 查看 V1.2.3 之後的所有變更
git log V1.2.3..

# 比較兩個版本之間的差異
git diff V1.2.3..V1.3.2

用日期定位版本#

# 找出某日期前的最後一次 commit
git rev-list -n 1 --before=2015-08-01 master

搜尋特定 Issue 的相關 commit#

git log --all --grep='Issue #1234'

檢視特定 commit 的內容#

git show 1cb6e3f6

用 git bisect 自動定位 Bug#

當你知道 bug 在某兩個版本之間被引入,且有一個能自動驗證的測試腳本時,git bisect 可以用二分搜尋自動找出引入 bug 的 commit:

git bisect start V1.1.0 V1.2.3
git bisect run test.sh
git reset

用 Branch 實驗修復方案#

Git 允許你建立 local branch 來實驗修復方案,成功則合併、失敗則刪除:

# 建立實驗分支
git checkout -b issue-work-1234

# 實驗成功 → 合併
git checkout master
git merge issue-work-1234

# 實驗失敗 → 刪除
git checkout master
git checkout -D issue-work-1234

用 git stash 暫存工作#

當你正在開發中但需要緊急處理另一個 bug 時:

git stash save interrupted-to-work-on-V1234
# 處理緊急 bug...
git stash pop

重點回顧#

  • 透過檢視檔案的版本歷史,可以發現 bug 何時及如何被引入
  • 利用版本控制系統比較正確版本與錯誤版本的差異
  • git bisect 可自動用二分搜尋定位引入 bug 的 commit
  • 善用 branch 和 stash 管理實驗性修復與工作切換