查看原文
其他

【第2645期】善用 Git 的 sparse checkout 跟 shallow clone/pull 來提高工作效率

Peter Dave 前端早读课 2022-12-20

前言

Git技巧,也许是不熟悉或没遇到过这样的场景。今日前端早读课文章由@Peter Dave分享。

正文从这开始~~

当初也是因为在摸比较肥大的项目才开始接触到的东西,不过貌似大家平常用不太到,所以很多人不知道有这样的功能,也是做个笔记,有人问的时候可以直接丢这篇 …

先讲 git shallow clone/pull:

man git-clone 理面的说明:

–depth
Create a shallow clone with a history truncated to the specified number of revisions.

简单来说就是把太久以前不需要的历史给丢掉,大于给定数量以前的 commit 纪录就会被忽略,进而省下 clone 时频宽、空间及时间,这点在数千到数万个 commits 以上的repository 里面效果会非常明显,像 Travis CI 在做 CI build 的时候预设的 clone depth 就是 50,很久以前是 100,缺点除了 git log 只看的到一定数量的提交纪录外,git blame 跟bi-sect 等会需要 trace 先前纪录的功能都会变的不可靠或不可用就是了。

另外一个就是 sparse-checkout 了,这个功能的作用是只 checkout 出我们想要的文件,以 cdnjs 为例,.git 文件夹也才600多MB而以,可是整个项目的文件夹却高达 13GB 左右,由于里面的文件大多是非常容易压缩的 source code(文字档),所以就会有 .git 文件夹明明占用很少空间,可是实际上整个项目占用的空间却非常庞大的现象,而这么大的项目,很可能会有文件系统操作的效率低下的问题(尤其在 rebase 等操作),在我们已知只需要取得某项目某些目录或文件的情况下,根本没必要把所有文件都 checkout 出来,这时候就可以使用 sparse-checkout,在送 pull request 到不是自己常态性参与的项目时很好用!

用法大概是这样(步骤2~4顺序可换):

1、建立一个空的 git 项目:

$ git init new.project && cd new.project

2、在项目里面启用 sparse-checkout:

$ git config core.sparseCheckout true

3、设置你要 checkout 哪些文件 (直接写到 .git/info/sparse-checkout,多个规则可写多行),例如我只要 /ajax/libs/jquery/ 底下的所有文件:

$ echo '/ajax/libs/jquery/*' >> .git/info/sparse-checkout

4、设定 remote (要从哪里clone/pull?):

$ git remote add origin git://github.com/cdnjs/cdnjs.git

5、然后就可以开始 pull 了(这边可以加上前面说的 shallow pull,加上 --depth=n ):

$ git pull origin master

到这边就完成了,整个项目所占用的空间应该会小非常多,这边以 cdnjs 搭配 shallow clone depth=10 为例,看一下空间使用:

$ du -d 1 -h
18M ./ajax
587M ./.git
605M .

总共605MB而已,而原本的长这样:

$ du -d 1 -h
682M ./.git
43M ./scratch
16M ./node_modules
12G ./ajax
24K ./test
32K ./build
13G .


高达 13GB … 少了 12GB 的 checkout 快了很多啊 …

如果之后想改变要 checkout 的文件呢?

就直接更改项目底下的 .git/info/sparse-checkout 档案,改好之后做一次 git reset --hard 即可(记得更改之前确认没有未储存的修改即可)

范例:

/ajax/libs/jquery/*
/build
/CONTRIBUTING.md
/MIT-LICENSE
/README.md
/sparseCheckout.md
//cdn2.peterdavehello.org/auto-update.js
/circle.yml
/CONTRIBUTING-WIP.md
//cdn2.peterdavehello.org/package.json
/update-script.sh

有一点要注意就是文件名前面代表项目根目录的斜线不要省略,若非要 checkout 所有同名文件,就要把完整路径写清楚,例如 /package.json 如果写成 package.json,则所有的 package.json 都会被 checkout 出来

关于本文
作者:@Peter Dave
原文:https://www.peterdavehello.org/2015/05/use-git-sparse-checkout-and-shallow-clone-pull-to-increase-work-efficient/

相关阅读


【第2623期】如何在 Monorepo 通过 Git 的 Sparse Checkout 取得部分 Repo 內容


欢迎自荐投稿,前端早读课等你

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存