在使用版本管理工具的过程当中咱们会碰到这样的问题:不当心把一个不应加入版本管理的文件加进去了,有时候这个文件很大,也许咱们整个版本库才几百 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