1. 程式人生 > 其它 >CI/CD_Git-大檔案問題定位和排查

CI/CD_Git-大檔案問題定位和排查

定位問題步驟一: 通過檔案大小檢視

下載的程式碼--檢視各個檔案的大小

du -h -d 1./

首先檢視包物件的

 git count-objects -vH 
 計算解包的物件數量及其磁碟消耗量

顯示所有的分支

 git branch -r | awk '{print $1}'	

###awk求和、平均值、最大小值
求和 cat data|awk '{sum+=$1} END {print "Sum = ", sum}'	 

檢視各個分支的大小 branch size stats

 for name in `git branch -r | awk '{print $1}'`; do echo -n $name" - "; git ls-tree -rl $name | awk '{sum+=$4}END{print sum / 1000000 "MB"}'; done | sort -k3g

定位問題步驟二:通過大檔案檢視

1.列出blob

找出要清理的大檔案
####找出排名前 5 的 pack 記錄:
 git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -g | tail -5
   35d21063a704dd90d241ae609af3f3f2ef14b321 blob    117450646 20768943 2317375723

2.blob的名稱和hash

列出提交包含的檔案--大檔案對應的hash和名稱
 ###第一行的字母其實相當於檔案的id,用以下命令可以找出id對應的檔名
       -- 根據上面提交id看檔案
       --- 找出大檔案所在的位置  git rev-list --objects --all|grep 35d21063a704dd90d241ae609af3f3f2ef14b321
       
       git rev-list --objects --all | grep 35d21063a704dd90d241ae609af3f3f2ef14b321
blob的內容和hash
 git cat-file 命令顯示版本庫物件的內容、型別及大小資訊
      git cat-file -p  35d21063a704dd90d241ae609af3f3f2ef14b321
 	  git cat-file -p 物件 hash 值 檢視物件的內容

3.blob對應的commit

Which commit has this blob? 
  控制顯示的記錄格式,常用的格式佔位符寫法及其代表的意義如下
    示例  
	obj_name="35d21063a704dd90d241ae609af3f3f2ef14b321"
    git log --all --pretty=tformat:'%T %h %s' \
    | while read tree commit subject ; do
        if git ls-tree -r $tree | grep -q "$obj_name" ; then
            echo "$obj_name" $commit "$subject"
        fi
    done
	
	##中文意思為,安靜模式,不列印任何標準輸出。如果有匹配的內容則立即返回狀態值0。 
      '%H': commit hash

4.commit相關的分支

git branch --contains 553095e --all

5. 檢視log

 git log --follow src/plng_nod237.txt

解決方式

方式一: 沒合併到主分支的情況下,刪除相應分支和使用到該commit 的分支

方式二: 使用filter-branch抹掉錯誤提交的大檔案提交記錄,徹底清理.git目錄
 ####處理大檔案 filter-branch  改寫了commit歷史
 git filter-branch --index-filter 'git rm --cached --ignore-unmatch   crawel.pdf '
 # git stash
 git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch crawel.pdf' --tag-name-filter cat -- --all
 –prune-empty 選項告訴git,如果因為重寫導致某些commit變成了空(比如修改的檔案全部被刪除),那麼忽略掉這個commit。
 –index-filter 選 項指定重寫的時候應該執行什麼命令,要執行的命令緊跟在它的後面,在這裡就是git rm --cached --ignore-unmatch 
 
 –tag-name-filter 表示對每一個tag如何重新命名,重新命名的命令緊跟在後面,當前的tag名會從標註輸入送給後面的命令,用cat就表示保持tag名不變。
 緊跟著的-- 表示分割符,
 最後的 -–all 表示對所有的檔案都考慮在內

說明

維護著一個微型的檔案系統,其中的檔案也被稱作資料物件。所有的資料物件均儲存於專案下面的 .git/objects	
Git維護兩個主要的資料結構:
    物件庫(object store)和索引(index)
   :塊(blob)、目錄樹(tree)、提交(commit)和標籤(tag)
   
    blob, 就是單個的檔案;   blob對應的commit的雜湊值
    tree, 就是一個資料夾   tree物件解決檔名的問題 
原理說明:
  使用filter-branch抹掉錯誤提交的大檔案提交記錄,徹底清理.git目錄
 1.出現原因:
  大檔案放到了專案下,提交的時候又push到遠端倉庫去了,雖然後來把檔案刪掉了重新提交,
  但Git儲存了每個檔案的前生後世 防止哪天又要找回你刪除過的檔案,
  導致專案下的.git子目錄依然存在這些大檔案的提交記錄,佔用大量空間
  git版本儲存導致大檔案仍會被記錄用於之後回滾需要
  
  .pack 是包檔案,這個檔案包含了從檔案系統中移除的所有物件的內容
  .idx是索引檔案,這個檔案包含了包檔案的偏移資訊
  
 2.解決方式
   用filter-branch,這個命令就可以修改歷史提交記錄,從而達到清理錯誤提交記錄。 
 需要提交就再執行
 git add  都會生成一個Git物件,稱為blob 物件,存放在objects目錄下
     將Blob物件合併成一個包檔案,同時會生成一個索引檔案,索引檔案中包含了每個Blob物件在包檔案中的偏移資訊,Git在打包的過程中使用了增量編碼方案
 	刪除pack中無用的大檔案快取
 	檢視提交記錄

參考

 https://stackoverflow.com/questions/223678/which-commit-has-this-blob/223890#223890