[教學] git-34 抓問題 - 討論區

[教學] git-34 抓問題

文章瀏覽次數 554 文章回覆數 2

特種兵

特種兵圖像(預設)

2020-05-03 11:31:56

From:1.161.142.239

前言

有時候程式或網站發生問題,並不會馬上就浮現,特別是小系統或者只有一兩個人在維運的狀況。

比較簡單的營運模式,可能會面臨到測試不夠完善或時間的關係無法把工作細分。

儘管已經很小心,但還是會發生錯誤的狀況,而這些錯誤可能是使用者操作時才會發現的。

例如工程師改了 A 這個地方,測試後發現沒問題,但忽略了 B 也會使用到這部分,沒有跟著修改的情況下,

當使用到 B 部分時就會發生問題,而 B 部分可能是久久才會使用到一次,等問題發生時可能已經是幾個星期以後的事情了。

這時候不管是要抓兇手或者追溯到問題發生的點都很困難,除了一個個認為有關的 commit checkout 過去查看以外,還有一個方法。

那就是類似二分搜尋的做法,將 commit 一直對半拆,最後就能找到問題,git 也提供這樣的機制,

指令是 bisect 當提交不多時又是自己做的專案,可能看一下 commit 訊息 checkout 幾次就能發現問題,

這時候 commit 就變得很重要,當一個較大的專案或 commit 寫不清楚的情況,有幾百個 commit 可能會 checkout 到瘋掉。

就算你已經知道是哪個檔案有問題,還是得一一的確認問題發生的始點,這相當花時間。

讓我們使用 bisect 快速的找到問題的提交並修復吧。

問題

不知道從什麼時候開始,xxx 廠商的匯入資料 excel 檔開始不再檢查身份證與統一編號了,造成不合規的字號被匯入系統當中。

我們先列出所有的 commit 然後找一個確定沒問題的 commit 好了:

其實隨便找一個 commit 也沒關係,反正可以 good 跟 bad 切換來切換去,找到只是時間問題而已。

流程

接下來要做的事情很簡單,不要被很多 commit 版號嚇住,我們這邊以 1 到 20 個 commit 為例簡單說明這個過程。

1 是最新的,20 是最舊的。一開始我們假設選了 12 號,

回答 bad 就會往前找一半的 commit 就是找比較舊的 12 到 20 之間,大概會找到 16

如果還是 bad 那就是落在 16 到 20 之間,可能是找到 18

如果是 good 就是落在 16 到 18 之間 應該是找到 17

那這樣就結束了。

再重新來一次,一樣 1 到 20 之間,我們找了 14 當開頭

回答 good 就是落在 1 到 14 之間,可能找到 7

回答 bad 就是落在 7 和 14 之間,可能找到 11

回答 good 就會落在 7 和 11 之間,可能找到 9

回答 bad 就會落在 9 和 11 之間,應該會找到 10

這樣就結束了

實做

好了,那就開始實做囉。

# 我這邊的 log 太多了,就先列 18 個就好
$ git log --oneline -18                                                         
 b7e9158 (HEAD -> master) Merge branch 'master' of 111.222.333.444:/test/project       
 d902703 Merge branch 'develope' of 111.222.333.444:/test/project                          
 0cc8cca 1.增加xxx額外匯入資料的controller判斷 2.增加xxx的身份證/統編格式判斷    
 c07da81 (origin/master, origin/HEAD) Merge branch 'develope'                        
 f3728fe (xxx) 在管理捐贈頁面新增是否為勸募的查詢條件                            
 b9d1614 讓編輯捐贈頁面顯示xxx的額外資訊與人資                                   
 7c6b0e3 設定匯入捐贈資料只有姓名時除非是年度收據否則就不查詢捐贈人是否存在      
 ba88427 將收據列印「 元整」前面的空格刪除                                       
 2c3c686 在單筆新增成功頁顯示是否為勸募                                          
 b19fb95 調整查詢捐贈人是否存在的邏輯                                            
 0630ac5 修正:讓是否為勸募正常顯示於編輯捐贈頁面                                
 72073ff 除錯:匯入禮物的狀態 0 問題                                             
 ca935dc 1.除錯-取得收據編號(寫反了) 2.除錯-找尋捐贈人羅輯調整                   
 0d07f72 取得收據編號之php函數已整合至系統                                       
 9fec99d 修改需要查詢捐贈人是否存在的開關變數名稱                                
 22958ce 1.把設定匯入資訊的函數和相關函數從model改成controller 2.把搜尋捐贈人是否
 存在的功能改到 inserting model                                                
 4e2f70d 修改取得單筆收據編號的函數,統一一次加一就好                            
 d16a1dc 除非是勸募,否則都會尋找年度收據編號,有找到就強制改為年度收據          

# 確定在 0cc8cca 還會檢查字號
$ git bisect start HEAD 0cc8cca                                                 
 Bisecting: 4 revisions left to test after this (roughly 2 steps)                
 [ba88427a20e430e7c5b5f806d71637ac4d204049] 將收據列印「 元整」前面的空格刪除    

git 會把我們的版本退到指定的版本的往前一半左右的一個 commit

從訊息可以看出是以指定版本再往前退了 4 個版,版號是 ba88427

接下來該怎麼做?

# 先看狀態再說
$ git status                                                                    
 HEAD detached at ba88427                                                        
 You are currently bisecting, started from branch 'master'.                      
   (use "git bisect reset" to get back to the original branch)                   

 nothing to commit, working tree clean                                           

因為現在處在特殊的 bisect 模式,所以有 HEAD detached 斷頭的字樣,代表有事情處理到一半。

也可以看到目前處於 ba88427 當中,這時候你可以查看相關檔案,

那些 git log 類的指令都能用,或者直接用瀏覽器開檔案看看此時還有沒有檢查字號的條件。

不想查了或是查好了,可以使用 git bisect reset 回到原本的 git 狀態。

# 看了一下,發現這時候還有檢查字號,所以我們得告訴 git 要他再往前找
$ git bisect bad                                                                
 Bisecting: 1 revision left to test after this (roughly 1 step)                  
 [0630ac53408288c7907b89db46971a7ba04b1d46] 修正:讓是否為勸募正常顯示於編輯捐贈 
 頁面                                                                            

所以 git 會再幫我們往前一半,就是對之前的 commit 再對半拆,這裡是 0630ac5

# 看了一下,這邊是沒有驗證字號的,他被註解掉了。看來範圍可以鎖定在 ba88427 與 0630ac5 之間的 commit
$ git bisect good                                                               
 Bisecting: 0 revisions left to test after this (roughly 0 steps)                
 [2c3c686a0a8d01da43a68e85415642e0530074d4] 在單筆新增成功頁顯示是否為勸募       

其實就剩兩個 commit 而已,非 A 及 B 的概念

# 發現這個 commit 也是把驗證字號註解掉的
$ git bisect good                                                               
 ba88427a20e430e7c5b5f806d71637ac4d204049 is the first bad commit                
 commit ba88427a20e430e7c5b5f806d71637ac4d204049                                 
 Author: Logo Kuo <logo@forblind.org.tw>                                         
 Date:   Fri Apr 24 16:17:53 2020 +0800                                          

     將收據列印「 元整」前面的空格刪除                                           

  abcd/test.php | 2 +-                                             
  1 file changed, 1 insertion(+), 1 deletion(-)                                  

# 找到了,就是他,從這個 commit 開始驗證就被註解掉了 

這個過程簡單說就是在 good 與 bad 之間找問題,bad 會往前找,good 會往後找。

這裡的往前找就是找比較舊的,往後找就是找比較新的。

當然找到這個 commit 也能使用之前的指令列出每一行是誰修改的,知道兇手以後我們去訪問他。

他說,因為當時再測試另外一個功能,覺得驗證身份證很煩,就先把他關掉,但後來忘記打開了。

最後,找好了就回到之前的狀態吧:

$ git bisect reset                                                              
 Previous HEAD position was 2c3c686 在單筆新增成功頁顯示是否為勸募               
 Switched to branch 'master'                                                     
 Your branch is ahead of 'origin/master' by 3 commits.                           
   (use "git push" to publish your local commits)                                

# 回來囉,再確定一下狀態
$ git status                                                                    
 On branch master                                                                
 Your branch is ahead of 'origin/master' by 3 commits.                           
   (use "git push" to publish your local commits)                                

 nothing to commit, working tree clean                                           

看來要更新一下進度了,好了,收工回家。

留言

#1

貓貓蟲

貓貓蟲圖像

2020-05-03 16:02:16

From:220.132.235.30

這些紀錄我好熟悉阿XDD

#2

特種兵

特種兵圖像(預設)

2020-05-09 04:52:36

From:1.161.140.241

呵呵…