在使用版本管理工具的過程當中咱們會碰到這樣的問題:不當心把一個不應加入版本管理的文件加進去了,有時候這個文件很大,也許咱們整個版本庫才幾百 K,但加進去這個沒用的文件卻有好幾百M,我可不想由於這麼個破爛東西把整個版本庫整個碩大無比,之後維護備份都不方便;還有時候是不當心把一個敏感文件 加進去了,好比裏面寫了信用卡密碼的文本文件。git
這時候咱們但願能把它從版本庫中永久刪除不留痕跡,不只要讓它在版本歷史裏看不出來,還要把它佔用的空間也釋放出來。app
在svn中的辦法是把整個版本庫dump出來filter一下再load回去。Git中能夠用下面的方法來實現:dom
咱們先建立一個試驗用的版本庫,並往裏面提交一個10M的大文件再刪除:svn
$ mkdir t $ cd t $ git init Initialized empty Git repository in /Users/apple/t/.git/ $ dd if=/dev/urandom of=testme.txt bs=10240 count=1024 1024+0 records in 1024+0 records out 10485760 bytes transferred in 1.684808 secs (6223712 bytes/sec) $ git add testme.txt $ git commit -m "a" [master (root-commit)]: created 6fbb432: "a" 1 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 testme.txt $ git rm testme.txt rm 'testme.txt' $ git commit -m r [master]: created bb38396: "r" 1 files changed, 0 insertions(+), 0 deletions(-) delete mode 100644 testme.txt
這時候咱們看看版本庫的大小:工具
$ du -hs 10M .
很明顯雖然testme.txt已經被刪除了,可是由於版本歷史裏曾經有過這個文件,因此git仍然把它存在庫中,之後能夠經過它再把它恢復回來。 但我實在是不但願這麼一個空版本庫佔用我10M寶貴的硬盤空間,因此我要把它全刪掉,這就要用到git的filter-branch命令了。具體這個命令的用法能夠看文檔,下面是這個例子中的用法:code
$ git filter-branch --tree-filter 'rm -f testme.txt' HEAD Rewrite bb383961a2d13e12d92be5f5e5d37491a90dee66 (2/2) Ref 'refs/heads/master' was rewritten $ git ls-remote . 230b8d53e2a6d5669165eed55579b64dccd78d11 HEAD 230b8d53e2a6d5669165eed55579b64dccd78d11 refs/heads/master bb383961a2d13e12d92be5f5e5d37491a90dee66 refs/original/refs/heads/master $ git update-ref -d refs/original/refs/heads/master [bb383961a2d13e12d92be5f5e5d37491a90dee66] $ git ls-remote . 230b8d53e2a6d5669165eed55579b64dccd78d11 HEAD 230b8d53e2a6d5669165eed55579b64dccd78d11 refs/heads/master $ rm -rf .git/logs $ git reflog --all $ git prune $ git gc $ du -hs 84K .
OK,這個文件已經完徹底全刪掉了,版本庫已經再也不佔用空間了。rem