git項目大小優化筆記,刪除歷史提交中的大文件
前言
不知不覺項目已經commit了一千多次,項目變成了107M。
是因為在項目的.git\objects\pack*.pack文件里會保留着歷史所有提交數據,並不會隨着文件的刪除而刪除該歷史提交記錄。
久而久之項目會變得越來越大。
最好的辦法是刪除遠程倉庫並且刪除本地項目下的.git文件夾,然后執行git init之后重新推送到新倉庫。
但是這會導致歷史commit記錄全都被刪除了,如果今后想回滾到某一次commit那就沒辦法了,公司也不允許這樣操作。
於是本小菜也來學習下優化git倉庫大小。
1.對歷史提交文件大小排序
在git bash窗口執行下面這段命令會依次對歷史提交中的文件大小進行排序
git rev-list --objects --all \
| git cat-file --batch-check='%(objecttype) %(objectname) %(objectsize) %(rest)' \
| sed -n 's/^blob //p' \
| sort --numeric-sort --key=2 \
| cut -c 1-12,41- \
| $(command -v gnumfmt || echo numfmt) --field=2 --to=iec-i --suffix=B --padding=7 --round=nearest
通過對歷史提交進行排序可以看到大部分都是因為這兩個文件夾里面的文件導致項目變大。
report/app/public/pdf/ 和 report/app/publish/font/
2.查看文件是否存在
要刪除大文件先要判斷文件是否可以被刪除。
轉到目錄report/app/public/pdf/ 和 report/app/publish/font/ 下面發現文件已經被刪除。
證明歷史提交中所有關於這兩個文件夾下面的文件引用都可以被刪除。
3.移除commit中某個文件的引用
該命令僅僅只是移除commit中對某文件的引用,如果某次commit同時提交了要刪除的文件和要保留的文件,該命令只會移除要刪除文件的引用,並不會移除要保留的文件和當次commit記錄,所以無需擔心會把不該刪除的文件刪掉了。
單獨移除某個文件的引用
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch 文件路徑/文件名' --tag-name-filter cat -- --all
移除某個文件夾下所有文件的引用,我想要移除report/app/public/pdf/文件夾下面所有文件的引用,所以我寫的report/app/public/pdf/*.*
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch report/app/public/pdf/*.*' --tag-name-filter cat -- --all
開始執行命令
命令執行完成
移除繼續移除report/app/public/font/文件夾下面所有文件的引用
git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch report/app/public/font/*.*' --tag-name-filter cat -- --all
4.刪除指向舊提交的指針
rm -rf .git/refs/original/
5.讓歷史記錄全部過期
設置所有未關聯對象過期時間為現在,默認為90天。
目的是放棄所有未關聯對象恢復的可能性,因為reflog 是找尋它們蹤跡的最后途徑了。
git reflog expire --expire=now --all
6.重新打包
執行完成后此命令后.git\objects\pack目錄下會生成新的打包文件,垃圾文件會保留在pack的上層目錄
git repack -A -d
7.對倉庫進行gc操作
執行完成此命令后,會把剛才repack的垃圾文件進行刪除,此時再看倉庫大小已經明顯被優化了。
git gc --aggressive --prune=now
8.強制推送到遠程分支
git push --force
9.以為這樣就完了?
還需要告訴一起開發的小伙伴,讓他們全部以clone的方式重新拉取代碼再做修改提交。
如果有人從優化前的代碼進行修改commit,那么上面所有操作都是無用功。