因为自己公司的gitlab被勒索病毒入侵,要把代码上传到github上,但由于文件超过100M,push被拒绝。

error tip:git large file storage
this exceeds GitHub's file size limit of 100.00 MB

各种百度

最后是用方法四搞定的

采用了以下方法:

方法1.执行取消push文件上传限制命令

git config http.postBuffer 824288000

方法2.git lfs github提供的大文件上传工具

gitlfs 添加大文件的命令
git lfs track "你的大文件名"
git add .
git commit -m "Add design file"
git push

ps:git lfs track 此命令执行成功后会生成 .gitattributes文件 git add 命令是将这个文件加入版本控制器

① 在最终push的时候会打印出如下信息:

Git LFS: (0 of 0 files, 1 skipped) 0 B / 0 B, 147.30 MB skipped

乍一看,表面上是跳过了该文件,但是回到github上查看,真的push上去了

② 目前 Git LFS的总存储量为1G左右,超过需要付费。

 

 

都没有解决问题

方法一:如果服务器没有限制,本地push限制可以用这种方法

方法二:这个是有单个大文件要上传github提供的工具。我的上传被限制是因为历史提交记录里面有超过100MB的大文件,虽然我已经把这个大文件删除了,但是在本repository的提交记录中还是存在的

 

 

方法三:git-filter-branch

du -d 1 -h

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

Git 维护着一个微型的文件系统,其中的文件也被称作数据对象。所有的数据对象均存储于项目下面的 .git/objects中。

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

Git与大部分版本控制系统的差别是很大的,比如Subversion、CVS、Perforce、Mercurial 等等,使用的是“增量文件系统” (Delta Storage systems), 就是说它们存储每次提交(commit)之间的差异。Git正好与之相反,它会把你的每次提交的文件的全部内容(snapshot)都会记录下来。这会是在使用Git时的一个很重要的理念。

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

如果想深入了解可以看看:https://www.jianshu.com/p/7231b509c279为什么你的 Git 仓库变得如此臃肿

https://www.jianshu.com/p/fa31ef8814d2Git 之术与道 -- 对象

 

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

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

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

rev-list命令用来列出Git仓库中的提交,我们用它来列出所有提交中涉及的文件名及其ID。 该命令可以指定只显示某个引用(或分支)的上下游的提交。

--objects:列出该提交涉及的所有文件ID。

--all:所有分支的提交,相当于指定了位于/refs下的所有引用。

verify-pack命令用于显示已打包的内容。

 

重写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请换成你第一步查出的大文件名,或者这里直接写一个目录。

filter-branch命令可以用来重写Git仓库中的提交

--index-filter参数用来指定一条Bash命令,然后Git会检出(checkout)所有的提交, 执行该命令,然后重新提交。

–all参数表示我们需要重写所有分支(或引用)。

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

Rewrite 6cdbb293d453ced07e6a07e0aa6e580e6a5538f4 (266/266) # Ref 'refs/heads/master' was rewritten

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

推送修改后的repo

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

git push

清理和回收空间

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

rm -rf .git/refs/original/
git reflog expire --expire=now --all
git gc --prune=now

 

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

 

 

方法四:git-filter-branch的替代品 (BFG Repo-Cleaner)

执行时间大大缩短,源码要通宵的工作,让你10分钟搞定。。。

需要安装java SDK才能运行

下载地址: bfg-xx-xx.jar

https://rtyley.github.io/bfg-repo-cleaner/

 

 

cd bfg.jar所在目录

java -jar bfg-1.13.0.jar --strip-blobs-bigger-than 50M git本地仓库目录

cd git本地仓库目录

git reflog expire --expire=now --all && git gc --prune=now --aggressive

git push

 

my 操作截图

导入项目到GitLab gitlab导入项目太大限制_导入项目到GitLab

 

 

导入项目到GitLab gitlab导入项目太大限制_git_02

 

 

导入项目到GitLab gitlab导入项目太大限制_github_03