使用git filter-branch刪除沒有使用的大文件
最近發現公司的iOS工程很大,.git文件夾足足2.5G,分析了下是以前把Pods目錄上傳到git了,以後忽略了這個文件夾,但是歷史提交還在裏面。優化後,減小到600M,這裏把方法分析給你們node
參考資料
https://www.jianshu.com/p/780161d32c8egit
準備
查看當前文件大小,優化先後使用對比 $ git count-objects -v -H數據庫
使用流程
1 查出已刪除的大文件前3名的commit SHA值
$ git verify-pack -v .git/objects/pack/pack-*.idx | sort -k 3 -n | tail -3
2 commit SHA值查出文件路徑
$ git rev-list --objects --all | grep <SHA>
Pods/opencv2/sdks/1.0.0/opencv2.framework/Versions/A/opencv2
到這裏,我就查出了個人.git爲何這麼大:把Pods提交上去了。作iOS開發的都知道這個是三方庫存的地方,不用提交到git。
3 查出文件提交commit記錄
$ git log --pretty=oneline --branches -- <file_path>
4 刪除文件
遍歷全部提交: commit多了會比較慢less
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch <file>' --tag-name-filter cat -- --all
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch Pods/' --tag-name-filter cat -- --all
我就是使用這個命令,全量刪除Pods目錄的
指定commit修改(配合步驟3使用)優化
$ git filter-branch -f --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch <file>' -- <commit_id>
5 回收內存
$ rm -rf .git/refs/original/
$ git reflog expire --expire=now --all
$ git fsck --full --unreachable
$ git repack -A -d
$ git gc --aggressive --prune=now
6 提交變更
$ git push --force --all
命令解析
1. git filter-branch
Rewrite branches 重寫分支日誌
- -f --force git filter-branch refuses to start with an existing temporary directory or when there are already refs starting with refs/original/, unless forced. git filter-branch拒絕從現有的臨時目錄開始,或者當已經使用refs / original /開始refs時,除非被強制。
- --prune-empty Some filters will generate empty commits that leave the tree untouched 某些過濾器將生成空提交,使樹保持不變
- --index-filter 'git rm -rf --cached --ignore-unmatch <file>' 使用帶有git rm的--index-filter會產生明顯更快的版本。與使用rm文件名同樣,若是文件不在提交樹中,則git rm --cached filename將失敗。若是你想「徹底忘記」一個文件,它在輸入歷史記錄時可有可無,因此咱們還添加了--ignore-unmatch
- --tag-name-filter This is the filter for rewriting tag names
- --tag-name-filter cat The original tags are not deleted, but can be overwritten
- -- --all filtered all refs
- -- tag 指定tag
2. git reflog expire --expire=now --all
Manage reflog information. reflog = reference log關聯日誌 git reflog expire The "expire" subcommand prunes older reflog entries. 「expire」子命令修剪舊的reflog條目code
- --all Process the reflogs of all references. 處理全部引用的reflog
- --expire=<time> Prune entries older than the specified time. 修剪早於指定時間的條目。
3 git fsck --full --unreachable
Verifies the connectivity and validity of the objects in the database 驗證數據庫中對象的鏈接性和有效性orm
- --unreachable Print out objects that exist but that aren’t reachable from any of the reference nodes.
- --full
4 git repack -A -d
Pack unpacked objects in a repository 在存儲庫中打包解壓縮的對象。 刪除冗餘的對象對象
- -a Instead of incrementally packing the unpacked objects, pack everything referenced into a single pack. 不是逐步打包解壓縮的對象,而是將引用的全部內容打包到單個包中。
- -d After packing, if the newly created packs make some existing packs redundant, remove the redundant packs. 打包後,若是新建立的包使一些現有包冗餘,請刪除冗餘包。 -A Same as -a, unless -d is used. Then any unreachable objects in a previous pack become loose, unpacked objects, instead of being left in the old pack. 與-a相同,除非使用-d。而後,前一個包中的任何沒法訪問的對象都會變成鬆散的解包對象,而不是留在舊包中。
5 git gc --aggressive --prune=now
Cleanup unnecessary files and optimize the local repository 清理沒必要要的文件並優化本地存儲庫內存
- --aggressive 此選項將致使git gc更積極地優化存儲庫,但代價是花費更多時間。
- --prune=<date> Prune loose objects older than date 修剪比日期更早的鬆散物體