最简单的github入门教程(Github使用教程图文详解)

最简单的github入门教程(Github使用教程图文详解)(1)

前提

在友人的提醒下,发先自己的github的项目体积过大,在只有一个src文件夹加上一些webpack配置,里面就2个HTML和一个输出console.log的js的情况下,项目体积竟然又13MB,这显然是不正常的,于是,开始解决这个问题!

问题所在

首先查看整个项目文件夹下的大小

$ du -d 1 -h 复制代码

发现是.git文件夹过大,然后一个一个点进去,.git->objects->pack ,里面的文件太大了,其中一个竟然有12MB。

原因

github在你执行git init操作后,会创建一个.git的隐藏文件夹,该目录结构如下

$ ls HEAD // 指向当前分支 branches/ // 目录 config // 项目特有的配置选项 description // 仅供 GitWeb 程序使用 hooks/ // 保存了客户端或服务端钩子脚本 index // 保存了暂存区域信息 info/ // 保存了一份不希望在 .gitignore 文件中管理的忽略模式 (ignored patterns) 的全局可执行文件 objects/ // 存储所有数据内容 refs/ // 存储指向数据 (分支) 的提交对象的指针 复制代码

在你git add 和 git commit 的过程中,保存修改了的文件的 blob,更新索引,创建 tree 对象,最后创建 commit 对象,这些 commit 对象指向了顶层 tree 对象以及先前的 commit 对象。这三类 Git 对象 ── blob,tree 以及 commit ── 都各自以文件的方式保存在 .git/objects 目录下。

所以,当你提交了一个体积特别大的文件后,会记录在objects文件夹下,删除一个文件,只是记录了删除这个操作,但并不会把文件从.git文件夹删除。 当你直接从项目中删除该文件,.git文件夹完全不会变小(理论上还会变大一点,因为多记录了一次删除操作。。。)。

git会记录你的每一次操作,这个是使用git中的很重要的概念

更多内容请点击git内部原理

解决

解决问题之前,请先出去抽支烟,确定自己清楚了这个操作的危险性。(建议先弄一个测试库试上几遍)

操作前提:删除所有的分支,只留下一个master

首先查找出大文件

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

rev-list命令用来列出Git仓库中的提交,我们用它来列出所有提交中涉及的文件名及其ID。 该命令可以指定只显示某个引用(或分支)的上下游的提交。 --objects:列出该提交涉及的所有文件ID。 --all:所有分支的提交,相当于指定了位于/refs下的所有引用。 verify-pack命令用于显示已打包的内容,我们用它来找到那些大文件。 -v(verbose)参数是打印详细信息。

前面我们通过rev-list得到了文件名-ID的对应关系,通过verify-pack得到了最大的5个文件ID。 用后者筛选前者便能得到最大的5个文件的文件名,比如:

$ git rev-list --objects --all | grep "$(git verify-pack -v .git/objects/pack/*.idx | sort -k 3 -n | tail -5 | awk '{print$1}')" b96695fd6e62fff41723ab324368da394f3a504e package-lock.json 76ec4d5d5fd79da922b322d53fbd1298dc128dd3 node_modules/acorn/dist/acorn.mjs.map 286dc92a240dac765d81dfbda451fd19f9611e84 node_modules/ajv/dist/ajv.bundle.js d2cc86eb230313af9bbdbd3faed7f8e7c7247788 node_modules/source-map-support/node_modules/source-map/dist/source-map.min.js.map aad0620d70e16717ec338fc1d332279739e0d97c node_modules/terser/node_modules/source-map/dist/source-map.debug.js 复制代码

然后我们需要删除他们

$ git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch YOU-FILE-NAME' --tag-name-filter cat -- --all 复制代码

filter-branch命令可以用来重写Git仓库中的提交 --index-filter参数用来指定一条Bash命令,然后Git会检出(checkout)所有的提交, 执行该命令,然后重新提交。 –all参数表示我们需要重写所有分支(或引用)。 YOU-FILE-NAME 你查找出来的大文件名字

重复几次,直到大文件全部删除完毕。

如果你确定某一个文件夹下面都不是你需要的,那么你可以直接删除整个文件夹,比如:

$ git filter-branch --force --prune-empty --index-filter 'git rm -rf --cached --ignore-unmatch node_modules' --tag-name-filter cat -- --all 复制代码

完成后,以强制覆盖的方式推送你的repo, 命令如下:

$ git push --force --all 复制代码

最后,虽然上面我们已经删除了文件, 但是我们的repo里面仍然保留了这些objects, 等待垃圾回收(GC), 所以我们要用命令彻底清除它, 并收回空间,命令如下:

$ rm -rf .git/refs/original/ $ git reflog expire --expire=now --all $ git gc --prune=now Enumerating objects: 116, done. Counting objects: 100% (116/116), done. Delta compression using up to 4 threads Compressing objects: 100% (53/53), done. Writing objects: 100% (116/116), done. Total 116 (delta 55), reused 116 (delta 55) 复制代码

经验教训

虽然折腾了半天,也成功解决了这个问题。

从中吸取了一个教训:

当你创建了项目后,没有设置好.gitignore之前,千万不要提交代码!!!还有就是,大文件尽量不要提交。

.gitignore设置: 在项目根目录创建.gitignore文件

.DS_Store node_modules /dist # local env files .env.local .env.*.local # Log files npm-debug.log* yarn-debug.log* yarn-error.log* # Editor directories and files .idea .vscode *.suo *.ntvs* *.njsproj *.sln *.sw* 复制代码

参考: 寻找并删除Git记录中的大文件 彻底删除git中没用的大文件

转载链接:https://juejin.cn/post/6844903848864137229

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页