Git ---- push时遇到大文件如何解决?

在做代码开源的时候,发现github有文件size的限制,超过100MB的大文件无法推送成功。

如何真正移除git文件且不影响版本库:

方法:使用 Rebase 或 filter-branch 指令來整理

1、git filter-branch 

$ git filter-branch --tree-filter "rm -f config/test.c"
Rewrite 27f6ed6da50dbee5adbb68102266a91dc097ad3f (7/7) (0 seconds passed, remaining 0 predicted)
Ref 'refs/heads/master' was rewritten

个人更使用喜欢参数为--index-filter或者--all filtered all refs;

$ git filter-branch -f --index-filter "git rm -f --cached --ignore-unmatch -fr config/test.c" A..B

参数--tag-name-filter cat 可以删除原始tag

2、这里的删除并不彻底,随时可以恢复文件,仅仅是回收内存的操作。我们需要清理所有散落的object和并删除git的备份 ,使其完全失效。

目录.git/refs/original下,还有相关备份:

$ rm .git/refs/original/refs/heads/master # $ rm .git/refs/original 删除git的备份

3、清理所有散落的object:

$ git reset refs/original/refs/heads/master --hard
or
$ git reflog&&git checkout $commit-SHA1

git reflog expire --all --expire=now

4、再次验证是否有散落的object, 验证数据库中对象的连接性和有效性,所以继续执行:


$ git fsck --unreachable 
 

5、git的垃圾清理车最终删除那些对象  git gc --aggressive --prune=now , --aggressive 此选项将导致git gc更积极地优化存储库,但代价是花费更多时间。

--prune=<date> Prune loose objects older than date 修剪比日期更早的松散物体。

可以在此之前执行 git repack -A -d 在存储库中打包解压缩的对象。

删除冗余的对象用$ git fsck #检查是否还有对应的object,现在已经找不到提交的sha1了。

$ git gc --prune=now 

可以使用该脚本查看大文件(https://github.com/appke/geekBigData/blob/master/findBigFile.sh)

#!/bin/bash
#set -x
  
# Shows you the largest objects in your repo's pack file.
# Written for osx.
#
# @see https://stubbisms.wordpress.com/2009/07/10/git-script-to-show-largest-pack-objects-and-trim-your-waist-line/
# @author Antony Stubbs
  
# set the internal field spereator to line break, so that we can iterate easily over the verify-pack output
IFS=$'\n';
  
# list all objects including their size, sort by size, take top 10 查出已删除的大文件前10名的commit SHA值
objects=`git verify-pack -v .git/objects/pack/pack-*.idx | grep -v chain | sort -k3nr | head`<br>
  
echo "All sizes are in kB's. The pack column is the size of the object, compressed, inside the pack file."
  
output="size,pack,SHA,location"
for y in $objects
do
    # extract the size in bytes
    size=$((`echo $y | cut -f 5 -d ' '`/1024))
    # extract the compressed size in bytes
    compressedSize=$((`echo $y | cut -f 6 -d ' '`/1024))
    # extract the SHA
    sha=`echo $y | cut -f 1 -d ' '`
    # find the objects location in the repository tree
    other=`git rev-list --all --objects | grep $sha`
    #lineBreak=`echo -e "\n"`
    output="${output}\n${size},${compressedSize},${other}"
done
  
echo -e $output | column -t -s ', '
  • 查看文件大小
du -ah .git/objects
  • 占用空间最多的五个文件 链接:https://www.jianshu.com/p/fe3023bdc825
git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"

git filter-branch -- 重写 branches: https://cloud.tencent.com/developer/section/1138641

git filter-branch [--env-filter <command>][--tree-filter <command>][--index-filter <command>][--parent-filter <command>]<br>[--msg-filter <command>][--commit-filter <command>][--tag-name-filter <command>][--subdirectory-filter <directory>]<br>[--prune-empty][--original <namespace>][-d <directory>][-f|--force][--][<rev-list options>…​]
 
 
--env-filter <command>   #修改将在其中执行提交的环境,常用于重写作者/提交者名称/电子邮件/时间环境变量。\<br>(GIT_AUTHOR_NAME,GIT_AUTHOR_EMAIL,GIT_AUTHOR_DATE,GIT_COMMITTER_NAME,GIT_COMMITTER_EMAIL,GIT_COMMITTER_DATE) e.g.
git filter-branch --env-filter '
    if test "$GIT_AUTHOR_EMAIL" = "root@localhost"
    then
        GIT_AUTHOR_EMAIL=john@example.com
        export GIT_AUTHOR_EMAIL
    fi
    if test "$GIT_COMMITTER_EMAIL" = "root@localhost"
    then
        GIT_COMMITTER_EMAIL=john@example.com
        export GIT_COMMITTER_EMAIL
    fi
' -- --all
 
--tree-filter <command>   #用于重写tree及其内容的过滤器。新增或删除文档
 
--index-filter <command>   #重写索引的过滤器。类似于树过滤器,但不检出树,因此速度更快。经常与结合使用git rm --cached --ignore-unmatch ...<br><br>##--tree-filter将每个提交签出到临时目录中,运行filter命令,并从临时目录中的任何内容生成新的提交;<br>##而--index-filter将每个提交复制到索引中,运行filter命令,并从索引中的任何内容生成新的提交。
 
--parent-filter <command> #用于重写提交的父列表的过滤器。它将在stdin上接收父字符串,并在stdout上输出新的父字符串。
 
--msg-filter <command>  #重写提交消息。
 
--commit-filter <command>  #执行提交的过滤器
 
--tag-name-filter <command>  #重写标签名称,原始标签不会被删除,但可以被覆盖;使用“ --tag-name-filter cat”来简单地更新标签。\<br>在这种情况下,请格外小心,并确保备份了旧标签,以防转换失败。
 
--subdirectory-filter <directory>    #只查看涉及给定子目录的历史记录
 
--prune-empty  #过滤常常生成空的提交,从而使树保持不变。此参会删除空提交。因此仅适用于只有一个父对象的提交它将保留合并点。与--commit-filter不兼容。
 
--original <namespace>   #使用此选项设置原始提交将存储在其中的名称空间。默认值是refs/original。
 
-d <directory>   #使用此选项可将路径设置为用于重写的临时目录。使用tree-filter, 该命令需要暂时将该树检出到某个目录,大型项目的情况下可能消耗很大空间。<br>默认情况下,它在.git-rewrite/目录中执行此操作,但您可以通过此参数覆盖该选项。
 
-f/--force    #git filter-branch拒绝从现有的临时目录开始过滤,或者当已经有ref时refs/original/,使用该参数强制执行过滤。
 
<rev-list options>…​  #参数git rev-list。<br>#所有positive refs都被重写。您也可以指定选项--all,但您必须使用--将修订选项与git filter-branch选项分开。--all重写所有分支和标记。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值