坑的由来

repo中不小心上传了许多测试生成的data。结果可想而知,原本只有代码的仓库突然间变得无比臃肿(或者是慢慢臃肿),从早期的几十MB,迅速飙升至1G.

到底发生了什么

早些时候我对git的原理并不是很了解,只是随着日常使用,终于开始理解git其实是一个指针指向一次提交的对象,当你在各个分支间切换的时候,指针就随之切换,版本也随之更改。

那么,git 是如何做到的能在各个版本间无缝切换的呢。即使long long ago的代码,只要来一句git reset --hard sesd54f54sdf5sd4sd5f 照样给你打回原形。

在相应的git文件夹里面 按下面组合键 可以看到隐藏的.git版本控制文件

ctrl+h

真相只有一个,那就是其实所有的版本,不管是否存在了多久,都仍然存在于硬盘里。所以你才可以任性地对代码为所欲为。然而,为所欲为也要付出代价。

代价就是,你删了几次,就会有几个快照存在于硬盘里。删一个大视频,表面上少了500M空间,实则增加了一次至少500M的历史提交记录,虽然现在的代码仓库里不再有这个视频,但是你试试du -sh .git看看.git 文件大小,是不是有惊喜?我在这儿体会的最恐怖的一次,见证了3个多G的.git

如何 解决

首先我们看看git相关文件占用的空间,运行

git count-objects -v

size-pack以千字节为单位表示,那么这里就有0.3G大小,这对代码仓库来说可是个恐怖的数字了。

那么让我们来找出罪魁祸首——到底是哪些大文件在混淆视听。

将所有含这些大文件的历史提交记录,一个不漏的找出来。

tail -30 表示 列举前30项

git rev-list --objects --all | grep -E `git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -30 | awk '{print$1}' | sed ':a;N;$!ba;s/\n/|/g'`

然后移除对该文件的引用 也就是 (tests_run_one.....后面一长串)  (使用filter-branch去除大文件)

git filter-branch --force --index-filter "git rm --cached --ignore-unmatch 'tests_run_one.....后面一长串'"  --prune-empty --tag-name-filter cat -- --all

进行repack

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin

# 指示Git清除不需要的数据:
git reflog expire --expire=now --all && git gc --prune=now --aggressive

查看pack的空间使用情况

git count-objects -v

查看.git的实际大小

du -sh .git

强制把本地的分支(这里是master)更改推送到git服务器分支

git push origin  --force --all

参数 origin 是远程仓库地址别名, 具体请参照 git remote -v 命令 查看选择
参数 --force 是强制推送, 这个参数表示强行覆盖远程仓库, 这个参数跟TNT一样危险不能乱用, 它可以简写为 -f
参数 --all 表示所有历史都要覆写, 当然我不知道这里的 “全部” 是多少, 教程里还提到了再提交一次 tags 的

强制push tags

git push origin  --force --tags

需要把这一次的改动提交到远端仓库:

git push --force --verbose --dry-run
git push --force

依次执行以下命令

rm -rf .git/refs/original/

git reflog expire --expire=now --all

git fsck --full --unreachable

git repack -A -d

git gc --aggressive --prune=now

git push --force

注:这一步可能会收到错误,原因是protected的分支不能进行覆盖推送,可以首先把当前分支修改为unprotected,在仓库的设置中可以修改。

到此,大文件已经从仓库中清除了,重新拉一个仓库,速度变快了,可以看到仓库的体积已经变小了,注意:一定要重新拉取仓库。

最后告诉你的同事使用pull rebase而不是使用merge来更新他们分支。如果使用merge,他们本地的.git可能会覆盖你之前做的清理工作,再次push 的时候会让本地仓库再次引入到远程库中

或者告知他们下次 重新git clone

 事实上有两种处理方法 参考gitlab官方文档 Reducing the repository size using Git

https://docs.gitlab.com/ee/user/project/repository/reducing_the_repo_size_using_git.html#reducing-the-repository-size-using-git

 如果要使用BFG清除git仓库中的隐私文件或大文件参考下面

https://www.cnblogs.com/huipengly/p/8424096.html

当repo只有默认的master的时候 以上是可以完成需求的

 

实验证明 如果repo 有其他分支(除了master分支之外) 以上指令没有效果 也就是远程端 并没有减少库容量 因为分支没有得到push 实际上--all参数是失效的

首先创建本地

查看远程分支名称

git branch -r

远程先开好分支然后拉到本地( 本地分支会和远程分支建立一定关联)

git checkout -b Tests origin/Tests //检出远程的Tests分支到本地Tests

查看本地分支 是否切换到刚创建的

git branch

 git gc

git for-each-ref --format='delete %(refname)' refs/original | git update-ref --stdin
git reflog expire --expire=now --all && git gc --prune=now --aggressive

强制 PUSH远程分支

git push origin Tests:Tests --force //推送本地的Tests(冒号前面的)分支到远程origin的Tests(冒号后面的)分支(没有会自动创建)

本文参考

https://blog.csdn.net/qq_40233736/article/details/86668768

https://kyriejoshua.github.io/jo.github.io/2016/07/17/how-to-clear-huge-files-in-git/

https://www.jianshu.com/p/17e5adf47da5

在git多分支repo仓库中彻底清除大文件的更多相关文章

  1. git 仓库中删除历史大文件

    git 仓库中删除历史大文件 在git中增加了一个很大的文件,而且被保存在历史提交记录中,每次拉取代码都很大,速度很慢.而且用删除 提交历史记录的方式不是很实际. 以下分几个步骤介绍如何减小.git文 ...

  2. 由于github仓库中提前建立readme文件,导致git push报错error: failed to push some refs to 'git@github.com:

    $ git push -u origin master To git@github.com:xxx/xxx.git ! [rejected] master -> master (fetch fi ...

  3. Linux系统中如何查找大文件或文件夹的方法

    在Windows系统中,我们可以使用TreeSize工具查找一些大文件或文件夹,非常的方便高效,在Linux系统中,如何去搜索一些比较大的文件呢?下面我整理了一下在Linux系统中如何查找大文件或文件 ...

  4. git操作:删除仓库中的文件或目录

    假定当前分支下,abc/123.txt需要从git仓库中删除: git .txt //删除abc目录下的123.txt文件,如果要删除abc目录,使用命令:git rm -r --cached abc ...

  5. 删除git中无用的大文件

    推荐阅读:为什么你的 Git 仓库变得如此臃肿 有时候我们不小心提交了一些大文件上去,后来删除了,但是已经于事无补了,整个git的提及已经蹭蹭上去了. 这个时候怎么办呢? 1. 查看有哪些大文件(to ...

  6. 快速清理maven仓库中下载错误的文件

    有时候使用pom文件下载依赖文件的时候突然网络异常,可能会出现依赖文件出现破损,导致怎么都不能使用,也没有重新下载. 之前解决办法是找到出现破损的文件并删除,让其重新下载,但是这样效率很低,也很难找到 ...

  7. 在python中逐行读取大文件

    在我们日常工作中,难免会有处理日志文件的时候,当文件小的时候,基本不用当心什么,直接用file.read()或readlines()就可以了,但是如果是将一个10G大小的日志文件读取,即文件大于内存的 ...

  8. 使用git在github远程仓库中操作

    在github上创建一个仓库,这一步参考廖雪峰老师的git教程,以及其他的一些准备工作略,我只记录几个重要的命令. 从其他github地址克隆项目 $ git clone git@github.com ...

  9. 忽略Git仓库中已经存在的文件

    解决方案 使用Git bash进入到要忽略的文件所在的文件夹,执行以下命令即可 git update-index --assume-unchanged rebel.xml 参考 Ignore Git ...

随机推荐

  1. python 反射机制在实际的应用场景讲解

    剖析python语言中 "反射" 机制的本质和实际应用场景一. 前言 def s1(): print("s1是这个函数的名字!") s = "s1&q ...

  2. java算法-单向队列

    队列是一种:先进先出,后进后出的数据结构 单项队列: 从前面删除元素,从后面插入元素,跟现实中排队是一样的道理 这里我们用指针移动位置的方法.因为数组删除元素,如果我们要跟现实中排队效果一样,就需要移 ...

  3. es6 语法 (字符串扩展)

    { console.log('a',`\u0061`); //a,a console.log('s',`\u20BB7`); //s ₻7 console.log('s',`\u{20BB7}`) / ...

  4. 【CSS学习】--- 文本水平对齐属性text-align和元素垂直对齐属性vertical-align

    一.文本水平对齐属性---text-align text-align属性是将块级标签以及单元格里面的内容进行相应的对齐,块级标签里的内联元素会被整体进行移动,而子块级元素或子单元格则会继承父元素的te ...

  5. 解决easyui combobox赋值boolean类型的值时,经常出现的内容显示的value而不是text的bug

    版本:EasyUI 1.7.0 在用easyui写项目时,碰到一个combobox的奇葩bug.代码如下: <div> <select class="easyui-comb ...

  6. 用ajax对数据进行删除和查看

    删除和查看详情操作的共同语句:就是怎么显示表? 1.在主体中写表的开头行,想要显示的内容,并且加载数据也要显示的地方也建张表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 & ...

  7. Loadrunner 脚本开发-利用web_submit_data函数实现POST请求

    脚本开发-利用web_submit_data函数实现POST请求   by:授客 QQ:1033553122 概述 web_link()和web_url()函数都是页面访问型函数,实现HTTP请求中的 ...

  8. WPF:自定义Metro样式文件夹选择对话框FolderBrowserDialog

    1.前言 WPF并没有文件选择对话框,要用也就只有使用Winform版的控件.至今我也没有寻找到一个WPF版本的文件选择对话框. 可能是我眼浊,如果各位知道有功能比较健全的WPF版文件选择对话框.文件 ...

  9. 【Spring源码解读】bean标签中的属性

    说明 今天在阅读Spring源码的时候,发现在加载xml中的bean时,解析了很多标签,其中有常用的如:scope.autowire.lazy-init.init-method.destroy-met ...

  10. 章节七、5-Maps

    一.向map集合中添加元素 map.put package ZangJie7; import java.util.HashMap; import java.util.Map; public class ...