1. 程式人生 > >Git永久刪除檔案(包括歷史記錄)

Git永久刪除檔案(包括歷史記錄)

有些時候不小心上傳了一些敏感檔案(例如密碼), 或者不想上傳的檔案(沒及時或忘了加到.gitignore裡的),

而且上傳的檔案又特別大的時候, 這將導致別人clone你的程式碼或下載zip包的時候也必須更新或下載這些無用的檔案,

因此, 我們需要一個方法, 永久的刪除這些檔案(包括該檔案的歷史記錄).

首先, 可以參考 github 的幫助:

  • 步驟一: 從你的資料庫中清除檔案

以Windows下為例(Linux類似), 開啟專案的Git Bash,使用命令:

git filter-branch --force --index-filter 'git rm --cached
--ignore-unmatch path-to-your-remove-file' --prune-empty --tag-name-filter cat -- --all

其中, path-to-your-remove-file 就是你要刪除的檔案的相對路徑(相對於git倉庫的跟目錄), 替換成你要刪除的檔案即可.

如果你要刪除的檔案很多, 可以寫進一個.sh檔案批量執行, 如果檔案或路徑裡有中文, 由於MinGW或CygWin對中文路徑設定比較麻煩, 你可以使用萬用字元號, 例如: sound/music_.mp3, 這樣就把sound目錄下以music_開頭的mp3檔案都刪除了.

例如這樣, del-music-mp3.sh:

#!/bin/bash

# git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch projects/Moon.mp3' --prune-empty --tag-name-filter cat -- --all
# git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch sound/Music_*.mp3' --prune-empty --tag-name-filter cat -- --all

如果你看到類似下面這樣的, 就說明刪除成功了:

Rewrite 48dc599c80e20527ed902928085e7861e6b3cbe6 (266/266)
# Ref 'refs/heads/master' was rewritten

如果顯示 xxxxx unchanged, 說明repo裡沒有找到該檔案, 請檢查路徑和檔名是否正確.

注意: 補充一點, 如果你想以後也不會再上傳這個檔案或資料夾, 請把這個檔案或資料夾新增到.gitignore檔案裡, 然後再push你的repo.

  • 步驟二: 推送我們修改後的repo

以強制覆蓋的方式推送你的repo, 命令如下:

git push origin master --force

這個過程其實是重新上傳我們的repo, 比較耗時, 雖然跟刪掉重新建一個repo有些類似, 但是好處是保留了原有的更新記錄, 所以還是有些不同的. 如果你實在不在意這些更新記錄, 也可以刪掉重建, 兩者也差不太多, 也許後者還更直觀些.

執行結果類似下面:

Counting objects: 4669, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (4352/4352), done.
Writing objects: 100% (4666/4666), 35.16 MiB | 51 KiB/s, done.
Total 4666 (delta 1361), reused 0 (delta 0)
To https://github.com/defunkt/github-gem.git
 1. beb839d...81f21f3 master -> master (forced update)
  • 步驟三: 清理和回收空間

雖然上面我們已經刪除了檔案, 但是我們的repo裡面仍然保留了這些objects, 等待垃圾回收(GC), 所以我們要用命令徹底清除它, 並收回空間.

命令如下:

rm -rf .git/refs/original/

git reflog expire --expire=now --all

git gc --prune=now
Counting objects: 2437, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (1378/1378), done.
# Writing objects: 100% (2437/2437), done.
# Total 2437 (delta 1461), reused 1802 (delta 1048)
git gc --aggressive --prune=now
Counting objects: 2437, done.
# Delta compression using up to 4 threads.
# Compressing objects: 100% (2426/2426), done.
# Writing objects: 100% (2437/2437), done.
# Total 2437 (delta 1483), reused 0 (delta 0)

現在你再看看你的.git目錄檔案大小是不是變小了.

參考自: