git因commit的记录太大导致push失败解决方法

发现好像这个方法不好使。。。。。。。~~!还是会失败

 

 

如果有人或者自己失误把不该同步的大文件如数据或日志或其他中间文件给commit了并且push了,然后你删掉了,但是其实他仍然在你的git记录中,你的整个项目仍然会非常大,主要是当时的那个删除你没有用git rm,但总之你想清理就很麻烦了现在,或者说,可能现在由于你commit的东西太大,导致了根本没法push上去,会出现类似

fatal: the remote end hung up unexpectedly

这样的错误,然后你就是需要清理一下你的commit记录了。

 

 

step 1. 把代码拉到本地

git clone git@github.com:hollischuang/Architecture-Evolution.git

只是用这个地址举例,实际并不是这个项目。

step 2. 查看哪个文件占用的空间比较大

于是,发现是.git目录自己就占用了174M,了解Git的人都知道,.git目录是git自己生成的,记录了git仓库的相关信息的。看到这里其实并不难知道原因。

经过我的验证,确实是.git/objects这个文件夹中的文件占了磁盘上174M的空间。

也就是说,只要我有一次将一个大文件误提交了,那么即使我后面把它删除了,但是,实际上在.git中,这个文件还是存在的,虽然我们可能再也不需要他了,但是他还在那里默默的存在着。。。

也就是说,如果我又一次把一个大文件务提交到git仓库中了,那么,下次提交时,即使你只改动了某个文件的一行内容,Git 也会生成一个全新的对象来存储新的文件内容。


因为以上两个特性,我回想起我的一次手残行为:
刚刚创建一个应用之后,我快速的写完代码,编译,运行,发现没啥问题之后,我准备先把他发布掉,于是我开始创建git仓库,并尝试把代码提交上去,这时我并没有创建.gitignore文件,我直接git add . git commit -m 'init'git push一气呵成的执行了熟悉的操作。

相信聪明的人已经发现了,逗比啊,我在编译代码之后,会有很多jar被我down到target目录下。我直接git add.把target下面的jar包,war包等这些也直接提交了。。。虽然后面我意识到,并且删除了这些文件,然后再次提交,但是由于刚我们说过的原因,这些文件依然占用着我的空间。。。

更多关于git的原理内容参见:Git 内部原理

How

问题已经定位到了,接下来就是要解决问题了。如果对git的原理及命令了解的比较多的话,这个问题还是比较好解决的,由于当时博主并不十分了解git的原理,所以做了一些知识储备之后才开始动手的。(Git 之术与道 — 对象为什么你的 Git 仓库变得如此臃肿

Step 1 查看哪些历史提交过文件占用空间较大

使用以下命令可以查看占用空间最多的五个文件:

git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"

step 2. 重写commit,删除大文件

使用以下命令,删除历史提交过的大文件:

git filter-branch --force --index-filter 'git rm -rf --cached --ignore-unmatch big-file.jar' --prune-empty --tag-name-filter cat -- --all

上面脚本中的big-file.jar请换成你第一步查出的大文件名,或者这里直接写一个目录。

在重写提交的过程中,会有以下日志输出:

如果显示 xxxxx unchanged, 说明repo里没有找到该文件, 请检查路径和文件名是否正确,重复上面的脚本,把所有你想删除的文件都删掉。

step 3. 推送修改后的repo

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

git push origin master --force

step 4. 清理和回收空间

虽然上面我们已经删除了文件, 但是我们的repo里面仍然保留了这些objects, 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间,命令如下:

至此,我们已经彻底的删除了我们不想要的文件

posted @ 2018-09-21 08:01  brady-wang  阅读(2229)  评论(0编辑  收藏  举报