• Git(七).git 文件夹瘦身,GitLab 永久删除文件


    一、问题背景

    由于项目在打 Docker 包的时候,需要将前端的包也打到 Docker 容器中,所以将前端包和前端的 Dockerfile 文件都放在了后端的 Git 目录下。

    久而久之,由于前端包的更新迭代,Git 上面会一直保留前端包的历史版本,所以整个后端的 .git 越来越大,截至目前已经有 2.44G 了。每次有新的小伙伴加入 git 后都需要花很长时间来拉取代码,苦不堪言,而且 Jenkins 上面新建项目的拉取也会超时。

    二、问题复现

    2.1 新建项目

    GitLab 上新建一个项目 my-test

    在这里插入图片描述

    我们可以看到,新建好的项目,默认只有 20KB

    在这里插入图片描述

    2.2 上传大文件

    执行命令将项目克隆到本地:

    git clone http://xxxx/xxx/xxx.git
    
    • 1

    此时,.git 文件夹大小为 30.7KB

    为了更加全面地测试,我们创建两个分支,并且分别上传文件。

    分支、文件结构对应关系如下:

    • dev-test1 分支

      | - pdf 文件夹

      ​ | - test_1.pdf 文件,12.8MB

      ​ | - test_2.pdf 文件,12.8MB

    • dev-test2 分支

      | - pdf 文件夹

      ​ | - test_1.pdf 文件,12.8MB

      ​ | - test_2.pdf 文件,12.8MB

    相关命令如下:

    # 创建dev-test1分支
    git checkout -b dev-test1
    git add -A .
    git commit -m "update test1"
    git push origin dev-test1
    
    # 创建dev-test2分支
    git checkout -b dev-test2
    git add -A .
    git commit -m "update test2"
    git push origin dev-test2
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    2.3 上传结果

    将大文件上传到 GitLab 后,仓库的大小如下:

    • .git11.2MB
    • GitLab11.3MB

    在这里插入图片描述

    三、解决方案

    注意:操作前要保证是最新版本。

    3.1 GitLab备份与还原

    1)备份

    在操作之前,我们要先备份 GitbLab 中的项目。最简单的方式就是直接将项目导出来。

    在 GitLab 上打开项目,进入菜单 Settings -> General -> Advanced,点击 Expand 打开折叠。

    在这里插入图片描述

    点击 Export project

    在这里插入图片描述

    可以看到提示,这个导出是一个异步的操作,当导出完毕之后会将通知发送到邮箱。

    在这里插入图片描述

    邮件中会有一个下载链接,点击链接下载,保存24小时。

    在这里插入图片描述

    下载后文件如下,文件名格式为:日期_时分秒_用户名_项目名.tar.gz

    在这里插入图片描述

    2)还原

    点击首页的 New project

    在这里插入图片描述

    选择 Import project

    在这里插入图片描述

    选择 GitLab export

    在这里插入图片描述

    输入项目名称,选择我们之前导出的 .tar.gz 文件,点击 Import project

    在这里插入图片描述

    还原完毕,分支和大小都在。

    在这里插入图片描述

    3.2 删除方式一:git filter-repo 命令【推荐】

    注意:git-filter-repo 工具需要依赖 Git 和 Python。

    1)安装
    # 安装(pip是Python自带的安装工具)
    pip install git-filter-repo
    # 查看版本
    git-filter-repo --version
    
    • 1
    • 2
    • 3
    • 4

    执行结果:

    在这里插入图片描述

    注意:git-filter-repo 需要在一个刚刚 clone 下来的仓库中进行操作,否则会操作失败。

    Aborting: Refusing to destructively overwrite repo history since
    this does not look like a fresh clone.
    (expected at most one entry in the reflog for HEAD)
    Please operate on a fresh clone instead. If you want to proceed
    anyway, use --force.

    在这里插入图片描述

    2)删除本地仓库文件

    git clone 到本地后立即执行如下命令:

    (不要做切换分支等操作,否则会报错,删除重新克隆才行。)

    # 模糊匹配,删除所有pdf文件(会同时删除pdf文件夹)
    git filter-repo --path-glob '*.pdf' --invert-paths
    
    # 补充:精确匹配,仅删除pdf/test_1.pdf
    git filter-repo --path-glob 'pdf/test_1.pdf' --invert-paths
    
    • 1
    • 2
    • 3
    • 4
    • 5

    执行结果如下:

    在这里插入图片描述

    git filter-repo 命令本身是用来将处理后的本地仓库重新推送到新的远程仓库用的,所以执行命令之后,查看 .git/config 配置文件,里面远程仓库的内容都被清空了:

    在这里插入图片描述

    执行之后,查看本地 .git 文件夹大小,从 11.2MB 直降至 32.8KB

    3)重新关联远程仓库

    重新关联远程仓库的命令如下:

    git remote add origin https://git.xxx.cn/acgkaka/my-test.git
    
    • 1
    4)删除远程仓库文件

    执行如下命令,将本地仓库的改动强制推送到远程仓库即可。

    git push --force origin --all
    
    • 1

    执行结果如下:

    在这里插入图片描述

    此时,GitLab 的远程仓库大小还是 11.2 MB,并无效果,别担心,还有最后一步操作。

    在这里插入图片描述

    4)clean up 清理远程仓库

    做完上面的操作之后,等待半小时,是的,等待30分钟,因为 GitLab 不会清理半小时内提交的文件。

    在 GitLab 上打开项目,进入菜单 Settings -> Repository -> Repository cleanup,点击 Expand 打开折叠。

    在这里插入图片描述

    在使用 clean up 时,需要提交一个文件,这个文件就是文件根目录下的 .git/filter-repo/commit-map

    在这里插入图片描述

    可以看到提示,这个导出是一个异步的操作,当cleanup完毕之后会将通知发送到邮箱。

    在这里插入图片描述

    邮件中会说明 cleanup 后的仓库大小,为 0.1MB

    在这里插入图片描述

    再去 GitLab 查看远程仓库大小,从 11.3MB 直降至 51KB,瘦身成功。

    在这里插入图片描述

    (经验证,这种方式删除掉的历史文件,即使有其他成员的本地仓库有未提交的版本,需要复制出来,删除本地仓库重新克隆后,再粘贴提交。)

    3.3 删除方式二:git branch-filter 命令【不推荐】

    注意: 目前经过尝试,发现 git branch-filter 虽然可以删除分支中的文件历史、提交记录,但是并不会减少 GitLab 中远程仓库的大小。

    1)删除本地仓库文件

    可以直接操作删除所有分支的文件,但是要注意必须保证所有分支都是最新代码才行。

    也可以切换到具体分支,执行 git pull 拉取最新代码后,再进行删除,只要去除后面的 -- --all即可。

    # 模糊匹配,删除所有pdf文件(会同时删除pdf文件夹)
    git filter-branch --force --index-filter "git rm --cached --ignore-unmatch '*.pdf'" --prune-empty --tag-name-filter cat -- --all
    
    # 补充:精确匹配,仅删除pdf/test_1.pdf
    git filter-branch --force --index-filter "git rm --cached --ignore-unmatch 'pdf/test_1.pdf'" --prune-empty --tag-name-filter cat -- --all
    
    • 1
    • 2
    • 3
    • 4
    • 5

    执行结果如下,可以看到 dev-test1dev-test2 分支被重写了。

    在这里插入图片描述

    2)删除远程仓库文件

    执行如下命令,将本地仓库的改动强制推送到远程仓库即可。

    # 推送本地所有分支到远程
    git push --force --all
    
    • 1
    • 2

    执行结果如下,可以看到 dev-test1dev-test2 分支被强制更新了。

    在这里插入图片描述

    我们可以去 GitLab 上面看下提交记录,"如果之前的提交只涉及被删除文件的话,对应提交记录就会被清空,如果提交中除了被删除文件之外还包含其他文件,那么提交记录和其他文件都会被保留,不受影响。

    在这里插入图片描述

    3)重新 repack 远程分支到本地

    执行如下命令,删除 refs/original 文件夹,并重新更新远程仓库到本地。

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

    执行之后,查看本地 .git 文件夹大小,从 11.2MB 直降至 32KB

    再次声明,这种方式虽然可以删除分支中的文件历史、提交记录,但是并不会减少 GitLab 中远程仓库的大小。远程仓库大小依然为 11.3MB。(有大佬知道后面怎么处理的,欢迎评论补充)

    在这里插入图片描述

    整理完毕,完结撒花~ 🌻





    参考地址:

    1.使用 git-filter-repo 清理 git 历史记录,https://nyakku.moe/posts/2020/06/12/use-git-filter-repo-clean-git-history.html

    2.利用git-filter-repo无缝迁移git项目,https://zhuanlan.zhihu.com/p/465078705

    3.git: 如何减少.git文件的大小?https://blog.csdn.net/LOI_QER/article/details/107911115

    4…git文件过大,github仓库瘦身,https://blog.csdn.net/luchengtao11/article/details/82531044

    5.从Git仓库(GitLab)中彻底去除大文件,https://zhuanlan.zhihu.com/p/589903338

    6.git 仓库越来越大,如何清理?https://juejin.cn/post/7254009710139146299

  • 相关阅读:
    【SLAM论文笔记】PL-EVIO笔记(下)
    python自动化测试面试题(四)(持续更新)
    LaunchPad 市场的复苏,Penpad 成新兴生力军
    简单理解精确率(Precision),召回率(Recall),准确率(Accuracy),TP,TN,FP,FN
    使用cv2将图片改为素描图
    基于Java的宠物医院管理系统设计与实现(源码+lw+部署文档+讲解等)
    【毕业设计】深度学习疲劳检测 驾驶行为检测 - python opencv cnn
    聊聊ChatGLM-6B部署与微调的深入理解
    FreeRTOS简单内核实现5 阻塞延时
    std::declval 源码分析
  • 原文地址:https://blog.csdn.net/qq_33204709/article/details/134173741