被吐槽 GitHub倉 庫太大,直接 600M 瘦身到 6M,這下舒服了

大家好,我是小富~

前言

忙裏偷閒學習了點技術寫了點demo代碼,打算提交到我那 2000Star 的Github倉庫上,居然發現有5個Issues,最近的一條日期已經是2022/8/1了,以前我還真沒留意過這些,我這人懶得很,本地代碼提交成功基本就不管了。

倉庫地址:https://github.com/chengxy-nds/Springboot-Notebook

5個Issues中,有個標題"優化本倉庫大小的建議"吸引我了,趕緊點進去看看啥情況,這個哥們說我這個倉庫太大了,倉庫700多M,半天也拉不下來,然後還給我附上了修改建議(不要太貼心哦)。

我不信

開始我還有點不信,這倉庫提交的是我平時寫文章中跑的代碼demo,每個項目也就十來個文件幾十KB,怎麼會有700M這麼多,不信邪的我趕緊看了下倉庫大小Setting->Repositoriess,居然真有683M這麼多。

於是我趕緊Clone倉庫到本地,看看是不是我提交了什麼大文件,下載過程確實挺折磨人,不僅慢還經常中斷,在經過不知道多少次重試之後,終於下載下來了。

翻了翻各個項目發現裏邊的確有許多應該忽略的文件.idea.mvntarget都被我提交了,直接刪除文件,但並沒有什麼卵用,項目整體size變化不大,應該不是這些文件的原因。

我用du命令看了下各目錄的文件大小,發現./springboot-seata-transaction目錄45M,因爲裏邊有一個jar直接刪除就行了;而 .git 足足有688M,看來問題就出在這個目錄,重點優化下。

這目錄好大

那麼.git目錄是存放什麼的?爲什麼會這麼大呢?

Git系統中,.git目錄中存儲了整個代碼倉庫的元數據信息(包括提交歷史記錄、分支、標籤等)和文件對象。

我在該目錄上用du命令看了一下,發現 objects 目錄居然有683M,那麼問題就是出在它身上了。

objects目錄之所以這麼大,是因爲它保存了倉庫中的所有歷史版本和數據對象,也就是blobs文件內容, trees目錄結構, commits提交歷史,它們是 Git 中的三個核心對象類型。

其中:

  • Blobs: 每一個文件都被視爲一個二進制對象(Blob 對象),它保存了文件的所有內容和一些元數據信息,如文件名、文件類型、文件大小等。當文件發生變化時,Git 會自動計算並存儲新的 Blob 對象,並將其與先前的 Blob 對象做比較,以確定文件的變化情況。

  • Trees: 目錄也被視爲一個對象(Tree 對象),它保存了目錄中包含的所有文件和子目錄的列表,每個列表項包括了文件或目錄的名稱、類型、權限等信息,以及對應文件或目錄的 Blob 或 Tree 對象的 SHA 校驗和。

  • Commits: 我們每次提交代碼,就會產生一次Commit, Commit對象保存了一次代碼變更的相關信息,包括作者、提交時間、父提交記錄的 SHA 值、描述信息等。每個 Commit 對象還包含指向對應代碼快照的 Tree 對象的 SHA 校驗和。

上邊三種類型的對象組成了Git中的基本數據單元,通過這些對象的組合和鏈接,才構建出完整的提交歷史,並跟蹤代碼庫中每個文件的變化歷史。這個目錄是Git中最重要的目錄之一,所以對它操作要謹慎,不然很容易丟失歷史記錄。

瘦身利器

儘管我們知道了大文件的位置,可具體該刪除哪些文件無從下手啊,objects目錄下都是些壓縮文件,弄不好整個倉庫都得報廢。

好在提Issues的兄弟還給推薦了個Git倉庫瘦身的工具,該說不說真的貼心啊。

這個Git倉庫清理工具叫BFG Repo-Cleaner,可以幫助我們篩選、清理大文件對象,官方文檔地址:https://rtyley.github.io/bfg-repo-cleaner ,接下來看看這工具咋用。

注意:在做以下操作之前,一定要備份!!! 一定要備份!!! 一定要備份!!!

1、下載安裝

BFG 是以java -jar的方式啓動,首先安裝不低於JDK8+ 的環境,並下載 BFG 的Jar包。

$ wget https://repo1.maven.org/maven2/com/madgag/bfg/1.14.0/bfg-1.14.0.jar

2、clone 倉庫

在 clone 倉庫的時候推薦使用--mirror參數,將源倉庫的所有分支、標籤以及提交歷史都完整地克隆到本地,只會拉取.git目錄的相關文件。

$ git clone --mirror git://example.com/Springboot-Notebook.git

3、查找大文件

bfg-1.14.0.jarSpringboot-Notebook.git 放在同一級目錄下,執行下邊的命令過濾出大於20M的文件對象。

# 查找出大於20M的需要清理的文件
$ java -jar bfg-1.14.0.jar --strip-blobs-bigger-than 20M Springboot-Notebook.git

看到過濾出了很多大文件,包含了Issues中兄弟提到的那個Jar包。

4、刪除大文件

使用--delete-files命令逐一的將大文件刪除,如果提示分支是被保護的可以加上--no-blob-protection命令執行。

# 查找出大於20M的需要清理的文件
$ java -jar bfg.jar --delete-files Cyrillic.traineddata  Springboot-Notebook.git 

5、GC 回收垃圾

上邊我們雖然過濾、刪除了大文件,此時倉庫的大小仍然沒有變化,進入Springboot-Notebook.git倉庫內,執行 git reflog expiregit gc命令,壓縮 Git 庫中的歷史版本、清除廢棄的、過期的對象,這個過程會耗費較長的時間。

# 進入目錄
$ cd Springboot-Notebook.git

# 執行git gc 回收垃圾
$ git reflog expire --expire=now --all && git gc --prune=now --aggressive

# 推送
$ git push

最後推送代碼到遠程倉庫,在看倉庫的大小已經降到了108M,效果挺顯著,剩下的108M應該就是我頻繁提交導致的了,查了下我居然有127次提交之多。

每次提交都會生成一次快照,這些快照可能包含大量的文件和代碼,頻繁提交會導致版本庫中快照的數量增加。Git使用的是一種增量存儲方式,每次提交只存儲發生了變化的文件和代碼。

但是,如果頻繁提交的變化較小,比如只是修改了幾個字符或者行末空格,Git可能無法正確地檢測出這些變化,而將整個文件都存儲起來,也會增加了.git文件的大小。

徹底一點

後來我想了想這個倉庫存在的意義,不就是讓大家看着文章跑demo代碼嘛,能快速的下載併成功運行纔是他們在乎的,誰又會在意提交記錄。那我乾脆徹底一點,清理掉倉庫的所有提交記錄,一勞永逸。

那麼操作起來就得小心一點了,畢竟2000star,別把倉庫弄嘎了,既要清除一個分支上的所有提交記錄,同時又不能刪除這個分支本身,其實我們可以迂迴一下。

我們首先使用 --orphan 命令創建一個全新的分支new-branch,這個新建的分支和其他分支沒有任何關係,它不會包含任何先前的提交記錄或者歷史記錄。相當於新建了一個乾淨的空分支,並讓該分支指向一個全新的根節點。

git checkout --orphan <new-branch-name>

然後 commit 全部的項目文件到這個分支,暫不需要推到遠程倉庫。

git add -A
git commit -am "Initial commit"

接着刪除舊的分支,並把新建的分支名改成舊分支名稱,推到遠程倉庫就行了。

# 

git branch -D <old-branch-name>
git branch -m <old-branch-name>
git push -f origin <old-branch-name>

在推完代碼後我再次去看了下倉庫的大小,現在就只有6.33M了,如果不是人臉識別項目中有幾個必要的SDK包,應該還能在小點。

總結

以我自己的親身經歷做爲反面教材,提醒大家操作Git要謹慎,工作中嚴禁提交該忽略的文件;提交代碼要控制節奏,不能隨心所欲,尤其是團隊協作開發;如果發現.git文件太大,推薦使用Git LFS來管理大文件,千萬不要像我這麼操作,畢竟隨意刪除提交歷史記錄,在哪個公司都是不合規的。

重點感謝下提出建議的大兄弟

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