IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> git 删除大文件记录解决拉取代码超时问题 -> 正文阅读

[开发工具]git 删除大文件记录解决拉取代码超时问题

背景

据研发同学反馈某次jenkins流水线编译代码时,一直不能检出代码,遂展开调查事故原因, 查看代码库就发现好家伙…代码存储竟然高达四百多兆, 这是个什么神仙代码库啊!!!

那么问题来了, 即便代码库很大为什么Jenkins拉取代码的时候会超时呢? 经过分析日志发现原来小丑竟是jenkins自己, 它居然弄了个十分钟超时的默认设置, 一般来说可以在Jenknins上修改超时时间来绕过这个问题. 但是由于我们平台的特殊性我们没办法马上改超时时间. 既然解决不了问题那么我们就想办法解决提出问题的人, 通过对代码库的进一步分析发现 有几个target目录特别大,没想到居然是研发同学在搞事情,连这中本地编译后生成的目录和文件都给提交了. 于是让研发同学删除后再试着拉取代码, 嗯… 结果可以说是不出所料依旧超时. 😰

原理

事情到这一步时候我们就需要了解一点git的原理了, Git 是一个内容寻址文件系统,核心部分是一个简单的键值对数据库(key-value data store)。 你可以向 Git 仓库中插入任意类型的内容,它会返回一个唯一的键,通过该键可以在任意时刻再次取回该内容。简单来说就是即使在代码中把大文件删除了.git 目录中仍然保存了大文件对象数据, 这导致了代码库占用存储过多,而且历史提交记录中仍然有对大文件的引用, 具体原理见
Git 内部原理 - Git 对象
Git 内部原理 - 维护与数据恢复


备用方案一, 精简代码库历史提交记录(推荐)

  • 先将原来的代码库复制一份做个备份, 避免精简提交记录的时候误删除导致文件无法恢复

  • 查看前五个最大的git对象, 可以根据自己需要修改tail -5

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

    效果如下

    user ~: git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')"
    c0e699fc5f6b32b6570c9f785d7c2f3c5b4954e2 target/test-report/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar
    9ee9c8d2497170f9f87d1ccf4e84e85e9240de1a target/test-sec/lib/rt.jar
    ba7f1017e3e31904bc5be9d12b1fb3c2c4646fa3 target/test-kafka/litest/kafka_2.11-1.1.0.jar
    234eb4a57e3a5c150db689a83a3b12e747ecb699 target/test-dia/doc/测试.docx
    181aa66aeb5570c83c8947a7fab6339f04d8265e target/test-sec.zip
    

    Git 往磁盘保存对象时默认使用的格式叫松散对象 (loose object) 格式
    Git 时不时地将这些对象打包至一个叫 packfile 的二进制文件以节省空间并提高效率
    git verify-pack 命令就是用于显示已打包的内容
    sort命令中 -k 指定排序参照列, -n 依照数值的大小排序
    tail命令 指定输出项数
    git rev-list 按照默认反向时间顺序,输出命令指定的commit objects
    --objects 列出的提交引用的任何对象的对象ID
    --all 全部匹配结果

  • 修改上一次提交, 从这一步开始的操作比较危险, 所以再强调一遍做好备份

    git commit --amend
    
  • 删除需要删除的文件或文件夹

    • 例如删除target/test-report/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar
      git filter-branch --force --index-filter "git rm -rf --cached --ignore-unmatch 'target/test-report/src/main/resources/lib/aspose-words-15.8.0-jdk16.jar'"  --prune-empty --tag-name-filter cat -- --all
      
    • 例如删除整个target文件夹历史
      git filter-branch --force --index-filter "git rm -rf --cached --ignore-unmatch 'target/*'"  --prune-empty --tag-name-filter cat ----all
      

      --force 拒绝从现有的临时目录开始,强制执行改写操作
      --index-filtertree-filter相比,不检查树,和git rm搭配使用,更快的生成版本
      --ignore-unmatch 如果你想“完全忘记”一个文件,在输入历史记录时无关紧要
      --prune-empty 表示如果修改后的提交为空则扔掉不要。实际可能虽然文件被删除了,但是还剩下个空的提交
      --tag-name-filter cat 来简单地更新标签
      --all 是针对所有的分支,注意前面多了一个 -- 这个是为了让分隔开git filter-branch--all

  • 清理优化

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

    git for-each-ref 输出指定位置所有reflog条目,--format 指定带有特定字符的Object
    git update-ref update reflog条目
    git reflog expire 删除掉--expire时间早的reflog条目
    git gc --prune= 对指定日期之前的未被关联的松散对象进行清理
    清理过后执行du -d 1 -h查看空间占用降下来了

  • 推送到远端仓库
    执行git push --force --verbose --dry-run 查看模拟推送会执行的操作

    --verbose 详细输出运行log
    --dry-run 做"真的update远程"以外所有工作
    执行git push --force 会直接推送新的更新到远端仓库, 如果远端仓库是gitlab的在gitlab界面上会看到远端仓库的空间实际上是增大的, 但是我们直接git clone后会发现和我们精简后的大小是一致的, 对于这种情况我们可以新建个干净的gitlab库之后再推送代码

更详细的操作过程见 https://www.cnblogs.com/bay1/p/10982254.html


备用方案二, git浅克隆

直接执行 git clone https://github.com/xxx/xxx.git --depth=1 克隆最近一次提交的完整代码, 会发现速度会快很多.git只会保留最近的提交, 当然–depth的数值可以自定义的

其他

Jenkins上有git浅克隆的实现, 也有svn增量检出机制的实现
如下:

  • git 浅克隆实现: [$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true, timeout: 30]
    checkout([$class: "GitSCM", branches: [[name: "${GIT_BRANCH}"]], doGenerateSubmoduleConfigurations: false,
    								extensions: [[$class: "CleanBeforeCheckout", deleteUntrackedNestedRepositories: true], 
    								[$class: 'CheckoutOption', timeout: 30], 
    								[$class: 'CloneOption', depth: 1, noTags: false, reference: '', shallow: true, timeout: 30]],
    								submoduleCfg: [], userRemoteConfigs: [[credentialsId: "${CERT_ID}", url: "$CODE_URL"]]])			
    
  • svn增量检出流水线实现: workspaceUpdater: [$class: "UpdateWithCleanUpdater"]
    checkout([$class: "SubversionSCM", additionalCredentials: [], excludedCommitMessages: "", excludedRegions: "", 
    		excludedRevprop: "", excludedUsers: "", filterChangelog: false, ignoreDirPropChanges: false, includedRegions: "", 
    		locations: [[cancelProcessOnExternalsFail: true, credentialsId: "${CERT_ID}", 
    		depthOption: "infinity", ignoreExternalsOption: true, local: ".", remote: "${CODE_URL}"]], quietOperation: true,
    	    workspaceUpdater: [$class: "UpdateWithCleanUpdater"]])
    
    svn检出策略请参考 https://www.cnblogs.com/wangle/p/14787202.html

参考

https://www.cnblogs.com/bay1/p/10982254.html
https://git-scm.com/book/zh/v2/Git-内部原理-Git-对象
https://www.cnblogs.com/wangle/p/14787202.html

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-09-04 01:32:17  更:2022-09-04 01:36:21 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/18 13:48:24-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码