git抽離與瘦身場景-抽離子項目以及刪除git中無用的大文件

目錄

1. 抽離場景---從大項目中抽離一個獨立文件夾作爲新的子項目

0. 查看git大小

1. 查看有哪些大文件(top 10)

2.在總項目之外任一地方創建一個空項目,並通過本地項目進行動態拉取項目

3.查看新項目目錄大小

2.瘦身場景--獨立項目刪減大文件(夾)場景

0. 查看git大小

1. 查看有哪些大文件(top 10)

2. git filter-branch

3. “遍”操作第一步和第二步

4. 刪除緩存下來的ref和git操作記錄

5. 垃圾回收

6. 查看git是否減少

7. 把.git裏面的修改推上去


推薦閱讀:爲什麼你的 Git 倉庫變得如此臃腫

可能在小白剛剛接觸git的時候,只是掌握了簡答的commit pull push clone等等的基本操作,在還沒有接觸.gitignore的時候,有時候會把一些大文件直接懟到git本地倉庫中,殊不知當時間一長久,git的項目就會逐漸變得龐大,那是一個多麼痛的領悟啊!!因此一定要摒棄杜絕這種養疽成患的習慣。

接下來就是根據自己平時的經驗總結如下幾個操作方法,對各個操作做了一次整合與記錄。實際的需求本人暫時分爲兩種。(還有哪些場景,還望各位大佬不吝賜教)

1. 抽離場景---從大項目中抽離一個獨立文件夾作爲新的子項目

2. 瘦身場景---獨立項目刪除大文件(file)/ 大文件夾(dir)

1. 抽離場景---從大項目中抽離一個獨立文件夾作爲新的子項目

此場景是因爲實際工作就是在一個項目中又有很多項目,混合開發,比如期初項目是一個javaweb項目,然而隨着業務發展,項目的開發模式開始走向前後端分離,那麼此時一些前端項目由react/vue/angular編寫,而所有後端業務邏輯由java承接,那麼有時候我們想在項目實際開發完成之後,剝離前端項目,(假設前端項目所有代碼放置於一個單獨文件夾下,或者通過重新組件一個文件夾,把這些項目放置於一個新文件夾中),那麼我們想把這個項目單獨抽離出來形成一個獨立的項目來進行單獨開發與維護,那麼我們怎麼操作。

閒話少說,show me the code。

我簡單分爲5步驟,

0. 查看git大小

$ git count-objects -v

count: 658

size: 13177

in-pack: 24533

packs: 4

size-pack: 5747555

prune-packable: 0

garbage: 0

size-garbage: 0

size-pack 爲 實際項目的大小以kb爲單位, 這裏5G大小,臥槽,這個就是一個超級大炸彈呢不是。要是在這5G文件大小中把除去只留下幾M大小的小項目,那無疑是大海撈針,太坑了。不過git給我們一個新功能,就是可以根據某個子目錄,並把子目錄相關的所有commit信息也一併抽取出來生成一個新分支,這個命令就是subtree命令

1. 查看有哪些大文件(top 10)

$ git subtree split -P ideaproject/reactapp_3d -b eapcubeweb

 ideaproject/reactapp 目錄存儲的是一個以react開發的web項目 -P <=> -Project(項目的意思)

eapcubeweb 是分支名, -b <=> -branch (分支的意思)

此時我們可以通過

$ git branch

* master

  eapcubeweb

看到有一個eapcubeweb 分支被創建

2.在總項目之外任一地方創建一個空項目,並通過本地項目進行動態拉取項目

mkdir ../eapcubeweb 創建一個目錄

cd ../eapcubeweb 進入目錄

git init 初始化git項目

git pull ../頂級項目目錄 eapcubeweb  從本地git項目中拉取項目以及對應的分支,此時只會拉取相關的refs

3.查看新項目目錄大小

$ git count-objects -v

count: 6

size: 1

in-pack: 2937

packs: 1

size-pack: 143318

prune-packable: 0

garbage: 0

size-garbage: 0

可以發現,我們從5G大小的大餅中,切了一小塊口子出來,生成了一個獨立的新項目,項目大小爲143M,對於一個項目來說143M顯然還是很大的,但是總比5G小太多了。我們如何進行更進一步地減少體積呢?那就是下面的將要將的瘦身活動了。

2.瘦身場景--獨立項目刪減大文件(夾)場景

此場景是因爲實際工作中會不自覺地將一些大文件或者一些敏感信息不小心直接commit到本地,後續又沒有做reset等操作(可能還不太清楚這個東西),因此大夥兒得過且過,就將就着用。那是又非常大的潛在風險的。尤其是一些敏感信息,讓我想到了bilibli泄漏事件,除去推廣成分,敏感信息往往是大家非常關注的,一旦不小心把敏感信息發佈出去,即使後期以commit重新修改方式,在有心人眼裏,還是能夠把“歷史”給扒出來看的。

閒話少說,show me the code。

我簡單分爲7步驟,

0. 查看git大小

$ git count-objects -v

count: 6

size: 1

in-pack: 2937

packs: 1

size-pack: 143318

prune-packable: 0

garbage: 0

size-garbage: 0

size-pack 爲 實際項目的大小以kb爲單位, 這裏143M大小

1. 查看有哪些大文件(top 10)

git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10 | awk '{print$1}')"

命令可以分爲如下兩步驟理解

1.1 查看有哪些大文件(top 10)

這個命令只能查看對應文件名hash值對應的文件類型以及文件大小,第三列單位爲字節(bytes),如下可以看到有一個非常大的文件,大致有130M左右

$ git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10

339bc58c7c3297d62cb8e5f2adb3411d44faa9c9 blob   901183 245971 14860559

f6e40f652575246527301158499a994d8c0da2b1 blob   901308 246024 4172051

a7e358eee7ec445f98be7e0643bdd897f048dfc8 blob   952135 112106 1942204

155d47e5efca426f4acfff12a69c587d8af590f0 blob   972382 373102 150876

85254d05a2e81de8a84c699dcf9005c964cc0688 blob   3586927 1049913 6310668

edaf3cc9e3b69918c145d6fe5bb1380d8aeeb943 blob   3831516 1613712 16797794 1 3d439f7ae0fd35157badef64a99e98f7e05c58ee

9e31acb78b79e0bb9c04c368da67ea0bcb4a04f2 blob   6637186 1303181 15106530

22a4a4234b6f41738ef4f7230c2786367b1efd2a blob   6637343 1303217 4418075

3d439f7ae0fd35157badef64a99e98f7e05c58ee blob   23890168 5321790 7360581

d2fdda3d1492d397b53a11055dfb87c093950c57 blob   134474097 127995889 18592453

1.2 查看有大文件對應的文件名(top 10)

我們需要知道對應的文件名,方便我們刪除文件

$ git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -10 | awk '{print$1}')"

155d47e5efca426f4acfff12a69c587d8af590f0 dist/js/echarts-all.js

a7e358eee7ec445f98be7e0643bdd897f048dfc8 undefined/css/main.86013fab.css.map

f6e40f652575246527301158499a994d8c0da2b1 undefined/js/34.ae2e8c03.chunk.js

22a4a4234b6f41738ef4f7230c2786367b1efd2a undefined/js/34.ae2e8c03.chunk.js.map

85254d05a2e81de8a84c699dcf9005c964cc0688 undefined/js/main.1599a4ca.js

3d439f7ae0fd35157badef64a99e98f7e05c58ee undefined/js/main.1599a4ca.js.map

339bc58c7c3297d62cb8e5f2adb3411d44faa9c9 dist/js/34.addd526f.chunk.js

9e31acb78b79e0bb9c04c368da67ea0bcb4a04f2 dist/js/34.addd526f.chunk.js.map

edaf3cc9e3b69918c145d6fe5bb1380d8aeeb943 dist/js/main.a2f9ed0b.js.map

d2fdda3d1492d397b53a11055dfb87c093950c57 node_modules.rar

2. git filter-branch

2.1  刪除大文件(file)

$ git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch node_modules.rar' --prune-empty --tag-name-filter cat -- --all

git filter-branch --index-filter 讓每個提交的文件都複製到索引(.git/index)中

然後運行過濾器命令:git rm --cached --ignore-unmatch 文件名 ,讓每個提交都刪除掉“文件名”文件

然後--prune-empty 把空的提交“修剪”掉

然後--tag-name-filter cat 把每個tag保持原名字,指向修改後的對應提交

最後-- --all 將所有ref(包括branch、tag)都執行上面的重寫

2.2  刪除大文件夾(dir)

刪除大文件夾下的所有內容,不用一個一個刪,提高刪除效率,比如實際應用中基於nodejs開發的前端項目,往往會在npm install安裝階段生成一個node_modules目錄,這裏是存儲當前項目關聯的包,可想而知,這個文件有多大,所以我們打算刪除以及在之前版本中加入到項目中的該文件夾下面的目錄,而且我們確信,刪除這個文件夾項目下所有文件對項目本身沒有任何關係,所以可以執行下面命令:

$ git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch node_modules' --prune-empty --tag-name-filter cat -- --all

跟刪除大文件類似,我們需要添加-rf 遞歸循環刪除文件夾下的所有文件

3. “遍”操作第一步和第二步

重複第一步和第二步,直到自己認爲沒有垃圾文件爲止,這裏同比與編譯原理的“”的概念。

4. 刪除緩存下來的ref和git操作記錄

$ git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin

$ git reflog expire --expire=now --all

與下方兩句一致

$ rm -rf .git/refs/original/

$ rm -rf .git/logs

這一步類似於jvm虛擬機中的刪除gcroot引用操作,也就是要把所有指向這個文件或目錄的記錄的引用都刪除了,方便垃圾回收機制處理垃圾。

5. 垃圾回收

上面2步把大文件的索引都切斷了,這個時候進行垃圾回收,就可以很明顯看到效果了 回收操作,.git目錄中的文件大小會立馬減少(git gc 並不會立馬看到 --prune意味着剪枝操作,也就是在在整個構造樹中減少所有文件)

$ git gc --prune=now           (立竿見影)

$ git gc           (暗流湧動)

6. 查看git是否減少

$ git count-objects -v

count: 0

size: 0

in-pack: 2752

packs: 1

size-pack: 2166

prune-packable: 0

garbage: 0

size-garbage: 0

經過上方一頓猛如虎的操作,我們看到size-pack減少到了2m,還是略有興奮的感覺。

7. 把.git裏面的修改推上去

這個時候普通的push是不行的,需要強推

git push --force

關於git push 出現無法提交的問題,可以通過

https://blog.csdn.net/yeshennet/article/details/77177522

來查看相關的信息

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章