Git遷移提示大檔案無法push的處理過程
因為自己公司的gitlab被勒索病毒入侵,要把程式碼上傳到github上,但由於檔案超過100M,push被拒絕。
error tip:git large file storage
this exceeds GitHub's file size limit of 100.00 MB
各種百度
最後是用方法四搞定的
採用了以下方法:
方法1.執行取消push檔案上傳限制命令
git config http.postBuffer 824288000
方法2.git lfs github提供的大檔案上傳工具
gitlfs 新增大檔案的命令
git lfs track "你的大檔名"
git add .
git commit -m "Add design file"
git push
ps:git lfs track 此命令執行成功後會生成 .gitattributes檔案 git add 命令是將這個檔案加入版本控制器
① 在最終push的時候會打印出如下資訊:
Git LFS: (0 of 0 files, 1 skipped) 0 B / 0 B, 147.30 MB skipped
乍一看,表面上是跳過了該檔案,但是回到github上檢視,真的push上去了
② 目前 Git LFS的總儲存量為1G左右,超過需要付費。
都沒有解決問題
方法一:如果伺服器沒有限制,本地push限制可以用這種方法
方法二:這個是有單個大檔案要上傳github提供的工具。我的上傳被限制是因為歷史提交記錄裡面有超過100MB的大檔案,雖然我已經把這個大檔案刪除了,但是在本repository的提交記錄中還是存在的
方法三:git-filter-branch
du -d 1 -h
瞭解Git的人都知道,.git目錄是git自己生成的,記錄了git倉庫的相關資訊的。看到這裡其實並不難知道原因。
Git 維護著一個微型的檔案系統,其中的檔案也被稱作資料物件。所有的資料物件均儲存於專案下面的 .git/objects中。
也就是說,只要我有一次將一個大檔案誤提交了,那麼即使我後面把它刪除了,但是,實際上在.git中,這個檔案還是存在的,雖然我們可能再也不需要他了,但是他還在那裡默默的存在著。。
Git與大部分版本控制系統的差別是很大的,比如Subversion、CVS、Perforce、Mercurial 等等,使用的是“增量檔案系統” (Delta Storage systems), 就是說它們儲存每次提交(commit)之間的差異。Git正好與之相反,它會把你的每次提交的檔案的全部內容(snapshot)都會記錄下來。這會是在使用Git時的一個很重要的理念。
也就是說,如果我又一次把一個大檔案務提交到git倉庫中了,那麼,下次提交時,即使你只改動了某個檔案的一行內容,Git 也會生成一個全新的物件來儲存新的檔案內容。
如果想深入瞭解可以看看:https://www.jianshu.com/p/7231b509c279為什麼你的 Git 倉庫變得如此臃腫
https://www.jianshu.com/p/fa31ef8814d2Git 之術與道 -- 物件
檢視哪些歷史提交過檔案佔用空間較大
使用以下命令可以檢視佔用空間最多的五個檔案:
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
rev-list命令用來列出Git倉庫中的提交,我們用它來列出所有提交中涉及的檔名及其ID。 該命令可以指定只顯示某個引用(或分支)的上下游的提交。
--objects:列出該提交涉及的所有檔案ID。
--all:所有分支的提交,相當於指定了位於/refs下的所有引用。
verify-pack命令用於顯示已打包的內容。
重寫commit,刪除大檔案
使用以下命令,刪除歷史提交過的大檔案:
git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch big-file.jar' --prune-empty --tag-name-filter cat -- --all
上面指令碼中的big-file.jar請換成你第一步查出的大檔名,或者這裡直接寫一個目錄。
filter-branch命令可以用來重寫Git倉庫中的提交
--index-filter引數用來指定一條Bash命令,然後Git會檢出(checkout)所有的提交, 執行該命令,然後重新提交。
–all引數表示我們需要重寫所有分支(或引用)。
在重寫提交的過程中,會有以下日誌輸出:
Rewrite 6cdbb293d453ced07e6a07e0aa6e580e6a5538f4 (266/266) # Ref 'refs/heads/master' was rewritten
如果顯示 xxxxx unchanged, 說明repo裡沒有找到該檔案, 請檢查路徑和檔名是否正確,重複上面的指令碼,把所有你想刪除的檔案都刪掉。
推送修改後的repo
以強制覆蓋的方式推送你的repo, 命令如下:
git push
清理和回收空間
雖然上面我們已經刪除了檔案, 但是我們的repo裡面仍然保留了這些objects, 等待垃圾回收(GC), 所以我們要用命令徹底清除它, 並收回空間,命令如下:
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now
至此,我們已經徹底的刪除了我們不想要的檔案。
方法四:git-filter-branch的替代品 (BFG Repo-Cleaner)
執行時間大大縮短,原始碼要通宵的工作,讓你10分鐘搞定。。。
需要安裝java SDK才能執行
下載地址: bfg-xx-xx.jar
https://rtyley.github.io/bfg-repo-cleaner/
cd bfg.jar所在目錄
java -jar bfg-1.13.0.jar --strip-blobs-bigger-than 50M git本地倉庫目錄
cd git本地倉庫目錄
git reflog expire --expire=now --all && git gc --prune=now --aggressive
git push
my 操作截圖