昨天突然有人跟我说我在gitlab上的一个仓库占用的内存很大,导致pull下来时间有点久。我检查了一下发现原来是我把几个大文件push上去了,而这几个大文件其实没必要传上去,很尴尬。。。因为这个gitlab仓库是大家公用的,所以今天上午在尝试如何把这几个大文件删除并且把记录抹去,虽然最后没有完全解决,但还是记录一下我尝试的过程。 这个故事告诉大家,在git add . 之后一定要检查一下自己加了什么,不要直接commit,然后push。。。 T-T
Git是一个可以记录你所有改动的工具,比如你在某个分支上进行了2次commit,在第一次commit的时候push了一个100M的文件,在第二次commit的时候,对文件进行了修改,然后再push上去,那么git仓库会记录下这两次的改动,也就是说这个git仓库会保存这两个100M的文件,即使你在第三次commit中把这个文件删除了,但是git还是会保存前面两次的记录,所以如果你想彻底删除某个文件也要一并删除之前的历史记录。 对于一些没必要的大文件,就不要上传到git仓库中,不然你的git仓库会越来越臃肿。 其他git原理可以参考 git原理
如果你是在某个分支上push的,而且这个分支没什么用,就直接删除该分支。
如果你是想删除的文件是在一次commit中上传的,可以通过代码回滚来回退到上传之前的状态。
git reset --hard commit_value但是假设你一共做了5次commit,是在第三次commit的时候上传了不想要的文件,可是第四次和第五次commit都做了一些其他改动,而且不想这些改动被撤销,该怎么办呢? 1)先创建一个和之前分支A一样的分支B 2)在分支A上做代码回退,回退到第三次commit之前的状态,这个时候在分支A上就只有第一次和第2次的commit信息,但是在分支B上有第一次到第五次的commit信息 3)通过git log查看到第四次和第五次commit的HASH值,然后在分支A上,通过git cherry-pick来将第四次commit 和第五次commit合并过来。
git checkout A git cherry-pick commit4_value git cherry-pick commit5_value合并过来之后,在分支A上就只有第一次、第二次和第四次、第五次commit的信息了,第三次commit的信息就被删除了,最后再把分支A push上去就OK了。
前面两种方法都是比较简单的情形。但假如你是突然发现你的git仓库有很多不必要的文件,但是可能经过多次commit上传上去的,如果通过之前的一次一次回退太麻烦了,或者说你想删除的文件在其他分支上也有。这个时候有一个命令可以帮到你:git filter-branch。这个命令要慎用。
git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch File_You_Want_to_Delete.jar' --prune-empty --all– prune-empty表示如果修改后的提交为空则扔掉不要 – all 表示重写所有分支 执行命令后会有以下输出:
$ git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch XXX.jar' Rewrite fd679c8b90abdf900b95e132bacb3300c04bcd01 (3/3) (1 seconds passed, remaining 0 predicted) rm 'XXX.jar' Ref 'refs/heads/test' was rewritten接着,再推送修改后的repo,并且清理和回收空间
git push --force rm -rf .git/refs/original/ git reflog expire --expire=now --all git gc --prune=now至此,在远端的git repo中就看不到你想要删掉的文件了。有关git filter-branch命令的更多用法可以参考 git 重写历史。 记一次删除Git记录中的大文件的过程。
用了以上的方法之后,我确实在远端看不到我想要删除的大文件了,也没有之前的commit记录了,可是在repo的信息这里还是显示的Files占据的空间很大。 图片上显示40M,实际只有几十K。不知道是不是因为我们公司的gitlab禁用掉gc了?下次在自己的github上试试看。