徹底刪除git中沒用的大文件

最近碰到個(gè)很難辦的問題,無(wú)意中發(fā)現(xiàn)項(xiàng)目文件夾已經(jīng)快1G了。。。
仔細(xì)一看,原來(lái)是.git文件夾占了80%。。。
思前想后也找不到原因,最后還是google了半天才找到問題:
之前為了方便把一個(gè)200M左右的sdk直接添加到了項(xiàng)目里,然后提交到git上了,更可怕的是sdk還換了好幾個(gè)版本提交了好多次。。。
所以git中就有N多這個(gè)sdk修改的記錄,占了很大空間;
為什么會(huì)出現(xiàn)這種情況呢,就是因?yàn)間it的存儲(chǔ)方式

git倉(cāng)庫(kù)下有一個(gè)名為 .git 的隱藏文件夾 ,從git初始化(git init)開始,所有倉(cāng)庫(kù)的變化都會(huì)記錄在這個(gè).git文件夾中;只要是git記錄的文件(add 并且 commit),就會(huì)通過(guò)一定的算法保存到這里,
刪除一個(gè)文件,只是記錄了刪除這個(gè)操作,但并不會(huì)把文件從.git文件夾刪除。
所以直接刪除項(xiàng)目中的文件,.git文件夾完全不會(huì)變?。ɡ碚撋线€會(huì)變大一點(diǎn),因?yàn)槎嘤涗浟艘淮蝿h除操作。。。)
要想徹底刪除git已經(jīng)記錄的文件,就必須用到一個(gè)高端命令:git filter-branch

官方解釋可以看這里:

https://git-scm.com/docs/git-filter-branch

https://git-scm.com/book/en/v2/Git-Tools-Rewriting-History

具體怎么使用可以參考這兩篇博客:

http://harttle.com/2016/03/22/purge-large-files-in-gitrepo.html

http://blog.csdn.net/lwfcgz/article/details/49453375

具體到我這兒,因?yàn)槲姨砑恿?XXX.framework的庫(kù),所以命令就是:

git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch XXX.framework' --tag-name-filter cat -- --all

各個(gè)參數(shù)的意思摘抄如下
filter-branch 是讓git重寫每一個(gè)分支,

--force 假如遇到?jīng)_突也讓git強(qiáng)制執(zhí)行,

--index-filter 選項(xiàng)指定重寫的時(shí)候應(yīng)該執(zhí)行什么命令,要執(zhí)行的命令緊跟在它的后面,在這里就是git rm --cached --ignore-unmatch password.txt ,讓git刪除掉緩存的文件,如果有匹配的話。

--prune-empty 選項(xiàng)告訴git,如果因?yàn)橹貙憣?dǎo)致某些commit變成了空(比如修改的文件全部被刪除),那么忽略掉這個(gè)commit。

--tag-name-filter 表示對(duì)每一個(gè)tag如何重命名,重命名的命令緊跟在后面,當(dāng)前的tag名會(huì)從標(biāo)注輸入送給后面的命令,用cat就表示保持tag名不變。

緊跟著的-- 表示分割符,

最后的--all 表示對(duì)所有的文件都考慮在內(nèi)。

等命令執(zhí)行完了,要提交到遠(yuǎn)程再

git push --force --all

就可以了

在實(shí)際操作中,我還遇到點(diǎn)其他問題,一并記錄下來(lái)~

  1. 因?yàn)閄XX.framework其實(shí)是個(gè)文件夾,所以在 rm 命令之后必須 加上 -rf 參數(shù),不然其實(shí)會(huì)漏刪不少東西
  2. 命令里面的 --all 似乎不怎么管用,至少對(duì)分支是不管用的,(博客1里面說(shuō)是對(duì)所有分支。。。貌似有點(diǎn)問題)
    一開始我項(xiàng)目有好幾個(gè)分支,我直接在master上操作,完了之后push,結(jié)果.git文件夾確實(shí)有變小,但變小的很有限。。。
    后來(lái)我把其他的分支備份出來(lái),然后刪掉項(xiàng)目里的所有分支,只剩下master,再來(lái)了一遍,果然就可以了,遠(yuǎn)程倉(cāng)庫(kù)果然變小了超級(jí)多
    本地的.git文件夾依然沒啥變化,這是因?yàn)橛泻芏啾镜鼐彺?,重新git clone遠(yuǎn)程就好了
  3. git push --force --all其實(shí)也是個(gè)很危險(xiǎn)的操作 ,再執(zhí)行這個(gè)之前,務(wù)必確保當(dāng)前代碼已經(jīng)是最新,并且你開始操作后沒有人提交過(guò)代碼,
    不然這么一force,有一大片沖突是必然的。。。不說(shuō)了,說(shuō)多了都是淚。。。

教訓(xùn):

sdk之類的大文件,盡量不要直接添加到git中,如果sdk不經(jīng)常更新且不太大(多大算大多大算小看各自網(wǎng)速了),那直接添加進(jìn)去問題也不大;
如果sdk比較大或者經(jīng)常更新,那就真的注意不能玩git里面加了,目前想到的比較好的替代方案有:

  1. 把sdk寫到.gitignore中,在readme等地方寫清楚,項(xiàng)目用到了什么sdk,讓用的人自己去下載;
    這個(gè)方法比較容易實(shí)現(xiàn),不過(guò)對(duì)用的人來(lái)說(shuō)不太友好。畢竟除了直接復(fù)制粘貼,直接git clone的代碼是不能直接用的。。。

  2. 用pod來(lái)管理
    一般來(lái)說(shuō)pods是不會(huì)放到git里面的,都是用的時(shí)候再pod install;所以可以給項(xiàng)目用到的sdk之類的大文件,專門建一個(gè)pod庫(kù),讓項(xiàng)目通過(guò)pod依賴這些大文件。
    這也是我現(xiàn)在用的方案,效果還是很不錯(cuò)的~
    再加上pod還可以配置一些依賴庫(kù)(方法可以參考https://github.com/Phelthas/LXMThirdLoginManager ,關(guān)鍵是.podspec文件),那就更加方便了!強(qiáng)烈推薦?。?!

有什么問題,歡迎討論~
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 本片內(nèi)容轉(zhuǎn)自CSDN http://blog.csdn.net/ithomer/article/details/7...
    五娃兒閱讀 5,044評(píng)論 2 87
  • Git是目前最流行的版本管理系統(tǒng),也是最先進(jìn)的分布式版本控制系統(tǒng)(distributed version cont...
    pro648閱讀 5,970評(píng)論 1 17
  • 項(xiàng)目組件化、平臺(tái)化是技術(shù)公司的共同目標(biāo),越來(lái)越多的技術(shù)公司推崇使用pod管理第三方庫(kù)以及私有組件,一方面使項(xiàng)目架構(gòu)...
    swu_luo閱讀 22,839評(píng)論 0 39
  • 在天還是白亮白亮的時(shí)候,我出了門。走出來(lái)才想到出門的原因是因?yàn)橥蝗活H有興致想四處看看,仿佛這熟悉的地方是我第一次來(lái)...
    summer_78f8閱讀 593評(píng)論 0 1
  • Hi,好久不見。 希望在遇到你時(shí)可以這樣打招呼。 今天中午休息的時(shí)候又成了被討論的話題,他們問我想找什么樣的,還沒...
    會(huì)飛的龍貓閱讀 525評(píng)論 0 2

友情鏈接更多精彩內(nèi)容