# Git LFS(Large File Storage) > [name=Sharon Mai] [time=20230524, Wed] [color=#907bf7] ## ↪️總目錄:[Git and GitHub相關](https://hackmd.io/@ppp300a/git-github/%2FZ2lh6kccQJqS9Zsp2Vcueg) :::success 情境:上傳GitHub時,當單個文件大小超過100MB出現無法上傳的錯誤訊息該如何解決呢? ::: ## 下載 [Git LFS](https://git-lfs.com/) ## 啟用 ``` git lfs install ``` ## 追蹤大型文件 > 使用Git LFS追蹤每個超過100MB的大型文件 - 本次範例為Detectron2的 `.pkl`文件 ``` git lfs track "*.pkl" ``` ## 創建 `.gitattributes`文件 > 告知Git哪些文件為大型文件處理 1. 在專案路徑中創建文件`.gitattributes`並與`.gitnore`同層級 2. 文件`.gitattributes`輸入: ``` .pkl filter=lfs diff=lfs merge=lfs -text <此處輸入大型文件相對位置> filter=lfs diff=lfs merge=lfs -text ``` 完成代碼如下: ``` .pkl filter=lfs diff=lfs merge=lfs -text backend/prj_webserver/detectron2_weights/model_final_f10217.pkl filter=lfs diff=lfs merge=lfs -text ``` ## 上傳 ### 加入 .gitattributes文件 ``` git add .gitattributes ``` ### 留言 ``` git commit -m "使用 Git LFS 跟踪大型文件" ``` ### 推送 ``` git push -u origin ai_test ``` 若無[錯誤訊息](#錯誤訊息)則成功! ## 錯誤訊息 > remote: error: Trace: 493715c1b5d40443d4dce3a849f2764022676f9516bf631617b5bc4a4b2a3091 remote: error: See https://gh.io/lfs for more information. remote: error: File yingmiai_webserver/detectron2_weights/model_final_f10217.pkl is 169.60 MB; this exceeds GitHub's file size limit of 100.00 MB remote: error: GH001: Large files detected. You may want to try Git Large File Storage - https://git-lfs.github.com. To https://github.com/name/prj.git ! [remote rejected] ai_test -> ai_test (pre-receive hook declined) error: failed to push some refs to 'https://github.com/name/prj.git' ### 原因 > Commit後發現有單個文件有超過100MB的大型文件存在。 ### 解決方式 #### 思路 >刪除本地端Push失敗的Commit歷史紀錄中的大型文件( model_final_f10217.pkl ),再設定好git FLS再繼續使用 :::danger 注意:將會使用到`--force`命令,請務必與開發團隊討論。 詳情請查看[注意事項](https://) ::: #### 流程 1. 將所有提交中刪除 model_final_f10217.pkl 文件 ``` git filter-branch --force --index-filter "git rm --cached --ignore-unmatch prj_webserver/detectron2_weights/model_final_f10217.pkl" --prune-empty --tag-name-filter cat -- --all ``` :::spoiler 命令說明 > 尚未深入瞭解先以ChatGPT所查到的紀錄為主。 > 原理:遍歷整個存儲庫的歷史,並在每個提交中刪除指定的文件。同時移除那些變為空的提交,並重寫所有的標籤和分支引用。在這個過程中,使用了一些選項和命令來確保即使在某些情況下可能出現的問題(如文件不存在,或臨時分支已存在)也能正確執行。 - `git filter-branch`:這是一個命令,它用於遍歷並修改 Git 存儲庫的所有 commit。 - `--force`:此選項允許 git filter-branch 命令忽略臨時分支是否已存在的檢查,如果存在,則直接覆蓋它們,避免出現錯誤。 - `--index-filter`:此選項允許您指定一個將在每個 commit 中運行的命令,這個命令用於修改 commit 的內容。在這個例子中,這個命令是 git rm --cached --ignore-unmatch yingmiai_webserver/detectron2_weights/model_final_f10217.pkl,它的作用是在每個 commit 中刪除指定的文件。 - `git rm --cached --ignore-unmatch`:此命令用於從 Git 索引(或稱暫存區)中移除文件。--ignore-unmatch 選項使命令在文件不存在時不會產生錯誤,而會繼續執行。 - `--prune-empty`:此選項會刪除所有因為前述操作而變成空的 commit。 - `--tag-name-filter cat -- --all`:此部分的命令用來重寫所有的標籤名稱和分支引用。cat 是一個 Unix 命令,它在這裡的作用是不改變標籤名(簡單地“返回”或“輸出”標籤名)。-- --all 則表示應用此操作到所有的分支和標籤。 ::: :::spoiler 命令執行流程 首先,git filter-branch 是一種強大的命令,允許我們在整個存儲庫歷史中對每個提交(commit)進行操作。在此使用 --index-filter 選項指定了一個命令,該命令會在每個提交上執行。 `git rm --cached`:這將從 Git 索引(也稱為暫存區)中移除文件。Git 索引是一個臨時區域,存儲了下一個提交的內容。因此,這個命令會使下一個提交不再包含被移除的文件。 `--ignore-unmatch`:這是一個選項,如果指定的文件在某個提交中不存在,它會使 git rm 命令繼續執行,而不是停止並報錯。 然後,`--prune-empty` 選項會移除那些變為空的提交,也就是那些由於文件刪除而不再包含任何更改的提交。 最後,`--tag-name-filter cat -- --all` 將重寫所有的標籤名稱和分支引用。在這個例子中,cat 命令簡單地返回(或輸出)原來的標籤名稱,所以標籤名稱並不會改變。 ::: 2. 清除 Git 緩存以釋放空間 ``` git reflog expire --expire=now --all && git gc --prune=now --aggressive ``` 3. 推送 ``` git push --force ```
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up