給你的git倉庫瘦身


很久沒有寫博客了,最近遇到了一個git問題,比較典型,記錄下來與大家分享。

我們使用git版本控制的時候享受了很多便利,不管是代碼合並,分支提供給我們的並發,但我們也往往忽略了每次提交之后在我們本地項目根目錄下.git文件夾里面的存儲變化。我遇到的git“臃腫”問題就是因為在提交的時候把較大文本加入版本控制,在其他人拉取更新反推遠程分支的時候,每一次都會加劇.git下面的objects的文件夾大小,最終的結果就是再也無法順利從遠程pull,也無法順利clone該項目。

關於.git的產生和相關文件,可見此文的詳細講解:http://www.jianshu.com/p/fa31ef8814d2 。


簡單的說,每一次提交修改的改變都會以文件的形式存儲在本地項目根目錄下的.git中,會在.git/objects下面形成一個Blob(一段二進制數據)文件記錄。這意味着,即使你只改動了某個文件的一行內容,Git 也會生成一個全新的對象來存儲新的文件內容。所以git倉庫隨着時間變化會自增長,我們往往忽視了這種潛在的危險。
下面來就我遇到的問題來思考解決方案,其實由於.git過大,我們可以從兩種方向去思考,第一種治標不治本的方法:壓縮git倉庫。第二種刪除git提交記錄中大文件,在gc壓縮。第一種方法是比較直接快捷的,可以使用命令:git gc --prune=now。 當你再次du -hs的時候會發現倉庫大小有一定的變小。其實git自身在可承受范圍內會自動用gc幫你壓縮打包,所以除非真的遇到pull,push都困難的時候,可以不用手動執行。這個方法明顯的缺點在於壓縮的效果有限,且大文件還一直在之后的每次提交中,為以后埋下隱患。


本人更推薦第二種方法,大文件對象再刪除。

先查找大文件,命令如下:

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


例如刪除nspatientList1.txt文件:

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch bin/nspatientList1.txt' --prune-empty --tag-name-filter cat -- --s

刪除之后會有大量輸出,顯示已經從各自歷史log中剔除掉關於這個大文件的信息,之后可以使用gc命令再次壓縮:

git gc  --prune=now

 

然后再進行提交即可。

你再次使用du相關命令檢測文件夾大小會驚奇地發現大幅度縮小。

 

當然也有人會說,這是你不斷地粗魯地merge造成的結果,所以也可以去使用rebase命令來衍合你的分支代碼,讓整個歷史log變成干凈清晰的一條直線。

關於rebase的使用可以參考官方文檔,一旦你接受了這種方式,你的git log會變得更美觀,也更符合人性。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM