最近clone一個倉庫發現文件夾巨大,查看具體文件體積並不大
後來發現是.git目錄佔用過多空間html
Git 往磁盤保存對象時默認使用的格式叫鬆散對象 (loose object) 格式
Git 時不時地將這些對象打包至一個叫 packfile 的二進制文件以節省空間並提升效率
而git verify-pack 命令就是用於顯示已打包的內容git
git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -3
sort命令中 -k 指定排序參照列, -n 依照數值的大小排序
tail命令 指定輸出項數bash
git rev-list 按照默認反向時間順序,輸出命令指定的commit objects
--objects 列出的提交引用的任何對象的對象ID
--all 所有匹配結果工具
git rev-list --objects --all | grep b098d1c7
上述兩個命令能夠合併成一個
這樣的輸出效果更明顯,方便
awk 命令是處理文本文件強大分析工具,{print$1} 表示每行按空格或TAB分割,輸出文本中第一項優化
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
git重寫歷史中,之前經常使用到的就是
修改上一次提交3d
git commit --amend
而咱們這一次所須要用到的內容是,「核彈級選項」 git filter-branch
它能夠修改大量的提交code
--force 拒絕從現有的臨時目錄開始,強制執行改寫操做
--index-filter 與tree-filter相比,不檢查樹,和git rm搭配使用,更快的生成版本
--ignore-unmatch 若是你想「徹底忘記」一個文件,在輸入歷史記錄時可有可無
--prune-empty 表示若是修改後的提交爲空則扔掉不要。實際可能雖然文件被刪除了,可是還剩下個空的提交
--tag-name-filter cat 來簡單地更新標籤
--all 是針對全部的分支,注意前面多了一個 -- 這個是爲了讓分隔開git filter-branch 和 --allorm
crnn/trained_models_crnn_Rec_done_155_1084.pth 爲你要刪除的文件名htm
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch 'crnn/trained_models_crnn_Rec_done_155_1084.pth'" --prune-empty --tag-name-filter cat -- --all
若是你想刪除整個文件夾歷史對象
git filter-branch --force --index-filter "git rm --cached --ignore-unmatch 'img/*'" --prune-empty --tag-name-filter cat ----all
git for-each-ref 輸出指定位置全部reflog條目,--format 指定帶有特定字符的Object
git update-ref update reflog條目
git reflog expire 刪除掉--expire時間早的reflog條目
git gc --prune= 對指定日期以前的未被關聯的鬆散對象進行清理
git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin git reflog expire --expire=now --all git gc --prune=now
這時候查看磁盤佔用空間
du -d 1 -h
--verbose 詳細輸出運行log
--dry-run 作"真的update遠程"之外全部工做
git push --force --verbose --dry-run
"真的update"
git push --force
最好的方法:不要把大文件放在git倉庫
參考文章:
如何解決 GitHub 提交次數過多 .git 文件過大的問題? - 鄭宇的回答 - 知乎
尋找並刪除Git記錄中的大文件
Pro Git
初次使用 git 的「核彈級選項」:filter-branch