1. 程式人生 > >Git遷移提示大檔案無法push的處理過程

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 操作截圖