zoukankan      html  css  js  c++  java
  • Git从库中移除已删除大文件

    写在前面
    大家一定遇到过在使用Git时,不小心将一个很大的文件添加到库中,即使删除,记录中还是保存了这个文件。以后不管是拷贝,还是push/pull都比较麻烦。今天在上传工程到github上,发现最大只能上传100MB大小文件,在本地git库中有一个150MB文件,虽然已经删除,但还保存了记录。下面教大家如何从库中彻底删除无效大文件。

    删除大文件
    方法很简单,就是先找到大文件对象再删除。

    先提交所有更改

    $ git commit -am "commit all"
    1
    对仓库进行gc操作

    $ git gc
    1
    运行count-objects 查看空间使用,size-pack 是以千字节为单位表示的 packfiles 的大小,因此已经使用了大约150MB 。

    $ git count-objects -v
    1


    运行底层命令 git verify-pack 以识别出大对象,对输出的第三列信息即文件大小进行排序.

    $ git verify-pack -v .git/objects/pack/pack-8eaeb...9e.idx | sort -k 3 -n | tail -3
    1


    注:可以看到对底下那个就是大文件。

    使用 rev-list 命令,传入 - -objects 选项,它会列出所有 commit SHA 值,blob SHA 值及相应的文件路径,这样查看 blob 的文件名。

    $ git rev-list --objects --all | grep 185ab8d
    1


    将该文件从历史记录的所有 tree 中移除。

    $ git log --pretty=oneline --branches -- spark-assembly-1.3.1-hadoop2.4.0.jar
    1


    用 filter-branch 命令重写从 646784 开始的所有 commit 才能将文件从 Git 历史中完全移除。

    git filter-branch --index-filter 'git rm --cached --ignore-unmatch spark-assembly-1.3.1-hadoop2.4.0.jar' -- 646784d95f347749517a67c50c117f4bf85d0b42..
    1


    注:- -index-filter 选项类似于 - -tree-filter 选项,但这里不是传入一个命令去修改磁盘上签出的文件,而是修改暂存区域或索引。不能用 rm file 命令来删除一个特定文件,而是必须用git rm - -cached 来删除它 ── 即从索引而不是磁盘删除它。这样做是出于速度考虑 ── 由于 Git 在运行你的 filter 之前无需将所有版本签出到磁盘上,这个操作会快得多。也可以用 - -tree-filter 来完成相同的操作。git rm 的 - -ignore-unmatch 选项指定当你试图删除的内容并不存在时不显示错误。最后,因为你清楚问题是从哪个 commit 开始的,使用 filter-branch 重写自 64678 这个 commit 开始的所有历史记录。不这么做的话会重写所有历史记录,花费不必要的更多时间。

    现在历史记录中已经不包含对那个文件的引用了。不过 reflog 以及运行 filter-branch 时 Git 往.git/refs/original 添加的一些 refs 中仍有对它的引用,因此需要将这些引用删除并对仓库进行 repack 操作。在进行 repack 前需要将所有对这些 commits 的引用去除。

    $ rm -Rf .git/refs/original
    $ rm -Rf .git/logs/
    $ git gc
    1
    2
    3
    查看空间使用

    $ git count-objects -v
    1
    如果真的要完全把这个对象删除,可以运行 git prune 命令。
    ---------------------
    作者:白 杨
    来源:CSDN
    原文:https://blog.csdn.net/zcf1002797280/article/details/50723783
    版权声明:本文为博主原创文章,转载请附上博文链接!

    http://blog.csdn.net/lihuanshuai/article/details/37345565

    Git的底层并没有采用 CVS、SVN 底层所采用的那套增量式文件系统,而是采用一套自行维护的存储文件系统。当文件变动发生提交时,该文件系统存储的不是文件的差异信息,而是文件快照,即整个文件内容,并保存指向快照的索引。这种做法,提高 Git 分支的使用效率;但也容易导致代码仓库中内容重复程度过高,从而仓库体积过大。当遇到这种情况时,或者需要将仓库推送到远程主机时,就需要Git中的gc(garbage collect)功能,也就是垃圾回收功能。

    大体来说,当运行 "git gc" 命令时,Git会收集所有松散对象并将它们存入 packfile,合并这些 packfile 进一个大的 packfile,然后将不被任何 commit 引用并且已存在一段时间 (数月) 的对象删除。 此外,Git还会将所有引用 (references) 并入一个单独文件。

    就细节而言,Git做了这几件事:

    • pack_refs 过程
    • reflog expire 过程
    • repack 过程
    • prune 过程
    • rerere 过程

    pack_refs 过程相当于执行"git pack-refs --all --prune",它会将$GIT_DIR/refs目录下的所有heads和tags打包成一个文件并保存为$GIT_DIR/packed-refs下。

    reflog expire 过程相当于执行"git reflog expire --all",它会将删除所有超过期限而且没有被refs涉及的reflog条目。

    repack 过程相当于执行"git repack -d -l",一般情况下还会包括"-A"选项,它会将所有未被包含在一个pack的松散对象连结成一个pack,也会将现有的pack重新组织为一个新的更有效率的pack,并删除冗余的pack(如果她们中存在不可达的松散对象,会先把这些对象释放出来)。

    prune 过程相当于执行"git prune --expire",他会删除所有过期的、不可达的且未被打包的松散对象。

    rerere 过程相当于执行"git rerere gc",这种情形下似乎没什么用。

  • 相关阅读:
    HTTP 错误 403.14
    HTTP 错误 404.3
    HTTP 500
    [转]ESCAPE()、ENCODEURI()、ENCODEURICOMPONENT()区别详解
    此计算机当前已将连接限制
    一个由表结构生成表的存储过程
    微信小程序页面跳转传参
    前端性能优化术语
    get请求和post请求的区别
    从输入url到页面呈现的过程
  • 原文地址:https://www.cnblogs.com/liangqihui/p/9880916.html
Copyright © 2011-2022 走看看