W3Cschool
恭喜您成為首批注冊用戶
獲得88經驗值獎勵
Git 也提供了兩個工具來輔助你調試項目中的問題。 由于 Git 被設計成適用于幾乎所有類型的項目,這些工具是比較通用的,但它們可以在出現(xiàn)問題的時候幫助你找到 bug 或者錯誤。
如果你在追蹤代碼中的一個 bug,并且想知道是什么時候以及為何會引入,文件標注通常是最好用的工具。 它展示了文件中每一行最后一次修改的提交。 所以,如果你在代碼中看到一個有問題的方法,你可以使用?git blame
?標注這個文件,查看這個方法每一行的最后修改時間以及是被誰修改的。 這個例子使用?-L
?選項來限制輸出范圍在第12至22行:
$ git blame -L 12,22 simplegit.rb
^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 12) def show(tree = 'master')
^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 13) command("git show #{tree}")
^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 14) end
^4832fe2 (Scott Chacon 2008-03-15 10:31:28 -0700 15)
9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 16) def log(tree = 'master')
79eaf55d (Scott Chacon 2008-04-06 10:15:08 -0700 17) command("git log #{tree}")
9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 18) end
9f6560e4 (Scott Chacon 2008-03-17 21:52:20 -0700 19)
42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 20) def blame(path)
42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 21) command("git blame #{path}")
42cf2861 (Magnus Chacon 2008-04-13 10:45:01 -0700 22) end
請注意,第一個字段是最后一次修改該行的提交的部分 SHA-1 值。 接下來兩個字段的值是從提交中提取出來的——作者的名字以及提交的時間——所以你就可以很輕易地找到是誰在什么時候修改了那一行。 接下來就是行號和文件內容。 注意一下?^4832fe2
?這個提交的那些行,這些指的是這個文件第一次提交的那些行。 這個提交是這個文件第一次加入到這個項目時的提交,并且這些行從未被修改過。 這會帶來小小的困惑,因為你已經至少看到三種 Git 使用?^
?來修飾一個提交的 SHA-1 值的不同含義,但這里確實就是這個意思。
另一件比較酷的事情是 Git 不會顯式地記錄文件的重命名。 它會記錄快照,然后在事后嘗試計算出重命名的動作。 這其中有一個很有意思的特性就是你可以讓 Git 找出所有的代碼移動。 如果你在git blame
?后面加上一個?-C
,Git 會分析你正在標注的文件,并且嘗試找出文件中從別的地方復制過來的代碼片段的原始出處。 比如,你將?GITServerHandler.m
?這個文件拆分為數(shù)個文件,其中一個文件是?GITPackUpload.m
。 對?GITPackUpload.m
?執(zhí)行帶?-C
?參數(shù)的blame命令,你就可以看到代碼塊的原始出處:
$ 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 會告訴你,你第一次寫這幾行代碼的那個提交才是原始提交,即使這是在另外一個文件里寫的。
當你知道問題是在哪里引入的情況下文件標注可以幫助你查找問題。 如果你不知道哪里出了問題,并且自從上次可以正常運行到現(xiàn)在已經有數(shù)十個或者上百個提交,這個時候你可以使用?git bisect
來幫助查找。?bisect
?命令會對你的提交歷史進行二分查找來幫助你盡快找到是哪一個提交引入了問題。
假設你剛剛在線上環(huán)境部署了你的代碼,接著收到一些 bug 反饋,但這些 bug 在你之前的開發(fā)環(huán)境里沒有出現(xiàn)過,這讓你百思不得其解。 你重新查看了你的代碼,發(fā)現(xiàn)這個問題是可以被重現(xiàn)的,但是你不知道哪里出了問題。 你可以用二分法來找到這個問題。 首先執(zhí)行?git bisect start
?來啟動,接著執(zhí)行?git bisect bad
?來告訴系統(tǒng)當前你所在的提交是有問題的。 然后你必須告訴 bisect 已知的最后一次正常狀態(tài)是哪次提交,使用?git bisect good [good_commit]
:
$ 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 發(fā)現(xiàn)在你標記為正常的提交(v1.0)和當前的錯誤版本之間有大約12次提交,于是 Git 檢出中間的那個提交。 現(xiàn)在你可以執(zhí)行測試,看看在這個提交下問題是不是還是存在。 如果還存在,說明問題是在這個提交之前引入的;如果問題不存在,說明問題是在這個提交之后引入的。 假設測試結果是沒有問題的,你可以通過?git bisect good
?來告訴 Git,然后繼續(xù)尋找。
$ git bisect good
Bisecting: 3 revisions left to test after this
[b047b02ea83310a70fd603dc8cd7a6cd13d15c04] secure this thing
現(xiàn)在你在另一個提交上了,這個提交是剛剛那個測試通過的提交和有問題的提交的中點。 你再一次執(zhí)行測試,發(fā)現(xiàn)這個提交下是有問題的,因此你可以通過?git bisect bad
?告訴 Git:
$ git bisect bad
Bisecting: 1 revisions left to test after this
[f71ce38690acf49c1f3c9bea38e09d82a5ce6014] drop exceptions table
這個提交是正常的,現(xiàn)在 Git 擁有的信息已經可以確定引入問題的位置在哪里。 它會告訴你第一個錯誤提交的 SHA-1 值并顯示一些提交說明,以及哪些文件在那次提交里修改過,這樣你可以找出引入 bug 的根源:
$ 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
當你完成這些操作之后,你應該執(zhí)行?git bisect reset
?重置你的 HEAD 指針到最開始的位置,否則你會停留在一個很奇怪的狀態(tài):
$ git bisect reset
這是一個可以幫助你在幾分鐘內從數(shù)百個提交中找到 bug 的強大工具。 事實上,如果你有一個腳本在項目是正常的情況下返回 0,在不正常的情況下返回非 0,你可以使?git bisect
?自動化這些操作。 首先,你設定好項目正常以及不正常所在提交的二分查找范圍。 你可以通過?bisect start
命令的參數(shù)來設定這兩個提交,第一個參數(shù)是項目不正常的提交,第二個參數(shù)是項目正常的提交:
$ git bisect start HEAD v1.0
$ git bisect run test-error.sh
Git 會自動在每個被檢出的提交里執(zhí)行?test-error.sh
?直到找到第一個項目不正常的提交。 你也可以執(zhí)行?make
?或者?make tests
?或者其他東西來進行自動化測試。
Copyright©2021 w3cschool編程獅|閩ICP備15016281號-3|閩公網安備35020302033924號
違法和不良信息舉報電話:173-0602-2364|舉報郵箱:jubao@eeedong.com
掃描二維碼
下載編程獅App
編程獅公眾號
聯(lián)系方式:
更多建議: