使用git filter-branch刪除沒有使用的大文件

使用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 修剪比日期更早的鬆散物體
相關文章
相關標籤/搜索