初次使用 git 的「核彈級選項」:filter-branch 從倉庫中刪除文件

當初看 Pro Git 時就被做者這個「核彈級選項」的稱呼嚇到了,所以一直沒敢好奇地去嘗試。核彈啊,用對了威力無窮,用錯了破壞力無窮!html

可是,今天,我不得不用了,由於我想把個人原來寫一些代碼放到 github 上去公開。因爲以前沒想過要公開,到上傳時才發現不能上傳大於50M的文件。java

折騰了半天,仍是沒法上傳,因而,整個命令出來了:git

  git filter-branch --tree-filter ' rm -rf files_to_remove ' --prune-empty -f HEAD --all

命令挺複雜的,因此我是在一個 clone 出來的倉庫裏先試運行。先解釋下各個參數:github

  • --tree-filter表示修改文件列表。
  • --msg-filter表示修改提交信息,原提交信息從標準輸入讀入,新提交信息輸出到標準輸出。
  • --prune-empty表示若是修改後的提交爲空則扔掉不要。在一次試運行中我發現雖然文件被刪除了,可是還剩下個空的提交,就查了下 man 文檔,找到了這個選項。
  • -f是忽略備份。不加這個選項第二次運行這個命令時會出錯,意思是 git 上次作了備份,如今再要運行的話得處理掉上次的備份。
  • --all是針對全部的分支。

試運行了幾回,看到 40 屢次提交逐一被重寫,而後檢查下,發現要刪除的文件確實被刪除了。因而高興地到 github 創建新倉庫,並上傳了。bash

折騰完畢,我更加喜歡 git 了 :-)工具

下面是具體的使用方法,主要是要gc,再覆蓋到遠程倉庫。spa

git filter-branch --index-filter 'git rm --cached --ignore-unmatch <your-file-name>'
rm -rf .git/refs/original/
git reflog expire --expire=now --all
git fsck --full --unreachable
git repack -A -d
git gc --aggressive --prune=now
git push --force origin master

------------------
2019-06-25更新,--all參數好像不能使用了,其實有更方便的第三方工具BFG可使用,支持指定文件大小和文件名。
https://rtyley.github.io/bfg-repo-cleaner/code

順便也寫下BFG的使用方式吧htm

首先倉庫要使用bare方式,克隆的時候要加上--bare或者--mirror選項。
ip

刪除100M以上的文件 

java -jar bfg.jar --strip-blobs-bigger-than 100M some-big-repo.git

刪除test.sdf文件 

java -jar bfg.jar --delete-files test.sdf some-big-repo.git

刪除_Boot 文件夾

java -jar bfg.jar --delete-folders _Boot some-big-repo.git

 最後要gc,再push到遠程倉庫

git reflog expire --expire=now --all && git gc --prune=now --aggressivegit push --force --all
相關文章
相關標籤/搜索