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