-
1. 開始
-
2. Git 基礎
-
3. Git 分支
-
4. 伺服器上的 Git
- 4.1 通訊協定
- 4.2 在伺服器上安裝 Git
- 4.3 產生您的 SSH 公鑰
- 4.4 設定伺服器
- 4.5 Git Daemon
- 4.6 Smart HTTP
- 4.7 GitWeb
- 4.8 GitLab
- 4.9 第三方託管選項
- 4.10 總結
-
5. 分散式 Git
-
A1. 附錄 A:在其他環境中使用 Git
- A1.1 圖形化介面
- A1.2 在 Visual Studio 中使用 Git
- A1.3 在 Visual Studio Code 中使用 Git
- A1.4 在 IntelliJ / PyCharm / WebStorm / PhpStorm / RubyMine 中使用 Git
- A1.5 在 Sublime Text 中使用 Git
- A1.6 在 Bash 中使用 Git
- A1.7 在 Zsh 中使用 Git
- A1.8 在 PowerShell 中使用 Git
- A1.9 總結
-
A2. 附錄 B:在應用程式中嵌入 Git
-
A3. 附錄 C:Git 命令
7.10 Git 工具 - 使用 Git 進行除錯
使用 Git 進行除錯
除了主要用於版本控制外,Git 也提供了一些指令來協助您除錯原始碼專案。由於 Git 的設計可以處理幾乎任何類型的內容,因此這些工具非常通用,但它們通常可以在出現問題時幫助您找到錯誤或問題原因。
檔案註解
如果您在程式碼中追蹤到錯誤,並想知道它是在何時引入以及原因,檔案註解通常是您的最佳工具。它會顯示每個檔案的每一行最後一次修改的提交。因此,如果您發現程式碼中的方法有錯誤,您可以使用 git blame
來註解該檔案,以確定哪個提交負責引入該行。
以下範例使用 git blame
來確定哪個提交和提交者負責最上層 Linux 核心 Makefile
中的行,此外,使用 -L
選項將註解的輸出限制為該檔案的第 69 行到第 82 行
$ git blame -L 69,82 Makefile
b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 69) ifeq ("$(origin V)", "command line")
b8b0618cf6fab (Cheng Renquan 2009-05-26 16:03:07 +0800 70) KBUILD_VERBOSE = $(V)
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 71) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 72) ifndef KBUILD_VERBOSE
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 73) KBUILD_VERBOSE = 0
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 74) endif
^1da177e4c3f4 (Linus Torvalds 2005-04-16 15:20:36 -0700 75)
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 76) ifeq ($(KBUILD_VERBOSE),1)
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 77) quiet =
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 78) Q =
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 79) else
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 80) quiet=quiet_
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 81) Q = @
066b7ed955808 (Michal Marek 2014-07-04 14:29:30 +0200 82) endif
請注意,第一個欄位是最後修改該行的提交的部分 SHA-1 值。接下來的兩個欄位是從該提交中提取的值 — 提交者的名稱和該提交的撰寫日期 — 因此您可以輕鬆查看誰在何時修改了該行。之後是行號和檔案的內容。另請注意 ^1da177e4c3f4
提交行,其中 ^
前綴表示在儲存庫的初始提交中引入且此後未更改的行。這有點令人困惑,因為您現在已經看到了 Git 使用 ^
修改提交 SHA-1 的至少三種不同方式,但這就是它在這裡的含義。
關於 Git 的另一個很酷的地方是,它不會明確追蹤檔案重新命名。它會記錄快照,然後在事後嘗試隱式找出哪些內容已重新命名。其中一個有趣的特性是,您可以要求它找出各種程式碼移動。如果您將 -C
傳遞給 git blame
,Git 會分析您正在註解的檔案,並嘗試找出其中程式碼片段的原始來源(如果它們是從其他地方複製過來的)。例如,假設您正在將名為 GITServerHandler.m
的檔案重構為多個檔案,其中一個檔案是 GITPackUpload.m
。透過使用 -C
選項註解 GITPackUpload.m
,您可以看到程式碼區段最初來自哪裡
$ git blame -C -L 141,153 GITPackUpload.m
f344f58d GITServerHandler.m (Scott 2009-01-04 141)
f344f58d GITServerHandler.m (Scott 2009-01-04 142) - (void) gatherObjectShasFromC
f344f58d GITServerHandler.m (Scott 2009-01-04 143) {
70befddd GITServerHandler.m (Scott 2009-03-22 144) //NSLog(@"GATHER COMMI
ad11ac80 GITPackUpload.m (Scott 2009-03-24 145)
ad11ac80 GITPackUpload.m (Scott 2009-03-24 146) NSString *parentSha;
ad11ac80 GITPackUpload.m (Scott 2009-03-24 147) GITCommit *commit = [g
ad11ac80 GITPackUpload.m (Scott 2009-03-24 148)
ad11ac80 GITPackUpload.m (Scott 2009-03-24 149) //NSLog(@"GATHER COMMI
ad11ac80 GITPackUpload.m (Scott 2009-03-24 150)
56ef2caf GITServerHandler.m (Scott 2009-01-05 151) if(commit) {
56ef2caf GITServerHandler.m (Scott 2009-01-05 152) [refDict setOb
56ef2caf GITServerHandler.m (Scott 2009-01-05 153)
這真的很有用。通常,您會將程式碼複製過來的提交作為原始提交,因為這是您第一次觸碰這個檔案中的這些行。Git 會告訴您撰寫這些行的原始提交,即使它是在另一個檔案中也是如此。
二分搜尋
如果您知道問題的起點,註解檔案會很有幫助。如果您不知道是什麼壞了,而且自您知道程式碼可運作的最後狀態以來已經有數十或數百次提交,您很可能會求助於 git bisect
來尋求幫助。bisect
指令會在您的提交歷史中執行二分搜尋,以協助您盡快找出哪個提交引入了問題。
假設您剛將程式碼的發行版本推送到生產環境,您正在收到關於開發環境中沒有發生的問題的錯誤報告,而且您無法想像程式碼為什麼會這樣做。您回到您的程式碼,然後發現您可以重現該問題,但您無法找出問題所在。您可以二分程式碼來找出答案。首先,您執行 git bisect start
來啟動,然後您使用 git bisect bad
來告知系統您目前所在的提交已損毀。然後,您必須使用 git bisect good <good_commit>
告訴 bisect 上次已知的良好狀態是什麼時候
$ git bisect start
$ git bisect bad
$ git bisect good v1.0
Bisecting: 6 revisions left to test after this
[ecb6e1bc347ccecc5f9350d878ce677feb13d3b2] Error handling on repo
Git 判斷出您標記為最後一個良好提交 (v1.0) 和目前錯誤版本之間大約有 12 個提交,並為您檢出了中間的那一個。此時,您可以執行測試來查看此提交是否存在問題。如果存在,則問題是在此中間提交之前的某個時間引入的;如果不存在,則問題是在此中間提交之後的某個時間引入的。結果發現這裡沒有問題,您只需輸入 git bisect good
告知 Git 並繼續您的旅程。
$ git bisect good
Bisecting: 3 revisions left to test after this
[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] Secure this thing
現在您位於另一個提交,它位於您剛測試的提交和您的錯誤提交之間的中間位置。您再次執行測試,發現此提交已損壞,因此您使用 git bisect bad
告知 Git。
$ git bisect bad
Bisecting: 1 revisions left to test after this
[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] Drop exceptions table
這個提交沒問題,現在 Git 擁有所有需要的資訊來判斷問題是在哪裡引入的。它會告訴您第一個錯誤提交的 SHA-1 值,並顯示一些提交資訊以及該提交中修改了哪些檔案,以便您可以弄清楚可能引入此錯誤的原因。
$ git bisect good
b047b02ea83310a70fd603dc8cd7a6cd13d15c04 is first bad commit
commit b047b02ea83310a70fd603dc8cd7a6cd13d15c04
Author: PJ Hyett <pjhyett@example.com>
Date: Tue Jan 27 14:48:32 2009 -0800
Secure this thing
:040000 040000 40ee3e7821b895e52c1695092db9bdc4c61d1730
f24d3c6ebcfc639b1a3814550e62d60b8e68a8e4 M config
完成後,您應該執行 git bisect reset
將您的 HEAD 重置為您開始之前的狀態,否則您最終會處於奇怪的狀態。
$ git bisect reset
這是一個強大的工具,可以幫助您在幾分鐘內檢查數百個提交是否有引入的錯誤。事實上,如果您有一個腳本,如果專案良好則退出代碼為 0,如果專案錯誤則退出代碼為非 0,則可以完全自動化 git bisect
。首先,您再次通過提供已知的錯誤和良好提交來告訴它二分法的範圍。如果您願意,可以使用 bisect start
命令列出它們,先列出已知的錯誤提交,然後列出已知的良好提交。
$ git bisect start HEAD v1.0
$ git bisect run test-error.sh
這樣做會自動在每個檢出的提交上執行 test-error.sh
,直到 Git 找到第一個損壞的提交。您也可以執行類似 make
或 make tests
或任何您用於執行自動化測試的命令。