文章

Git lfs

Git lfs

Git lfs

什么是 lfs

Git LFS(Large File Storage),用以帮助 git 管理比较大的文件。git 的 diff 等是基于文件。对于二进制文件来说,git 需要存储每次提交的变动。git fls 对于追踪的文件只会保存一个指向其的指针。不会在本地仓库保存你每次提交的所有版本。对于历史提交版本,基本上我们都很少去动,不需要检出。所以这样极大的节省了空间和仓库拉取速度。
核心:把需要进行版本管理、但是占用很大空间的文件独立于 Git 仓库管理,加快 clone 仓库速度。

安装 Git lfs

lfs 目前是 git 扩展,没有被加入 git 核心。所以就需要有个安装的步骤。
注意:安装 git lfs 需要 git 版本>=1.8.2

1
2
3
4
5
6
7
8
9
10
11
12
# mac下请使用homebrew安装:
brew install git-lfs
git lfs install

# linux(unbuntu)下安装:
curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
apt-get install git-lfs

# Windows
## 下载安装windows installer
## 运行windows installer
## git lfs install

常用命令

  • git lfs ls-files 可以显示当前被 lfs 追踪的文件列表
  • git lfs track “xx. a” 告诉 lfs 需要处理哪些文件

此命令执行后,会在项目根目录下创建一个名为 “. gitattributes” 的文件;. gitattributes 文件是需要加入版本控制的。

  • git lfs untrack "*xx. a" 取消 git fls 对 xx.a 的追踪管理
  • git lfs version 查看当前所用 git lfs 版本
  • git lfs pull 如果起之前拉代码时,没有同时获取 lfs 对象,之后又需要将被 lfs 追踪的文件时,可执行此命令来拉取

使用 Git lfs

1
2
3
4
5
6
7
8
9
10
11
12
13
# 1. 安装完成后,首先先初始化;如果有反馈,一般表示初始化成功
git lfs install

# 2. 如果刚刚下载的那个项目没啥更改,重新下一遍,不算麻烦事(因为下载大文件,一般会比较慢)
git lfs clone https://github.com/AABBBCC/aaa.git
# 在下载的过程中,你也可以查看一下,你刚刚无法解析的那个pkl大文件,是不是在这个项目中,(进入项目目录)使用如下指令:
cd aaa
git lfs track

# 3. 如果不想重新下载整个项目,可以使用如下命令,单独下载需要使用lfs下载的大文件。
git lfs fetch
git lfs checkout
#(备选:git lfs pull),不建议

Git 拉取大仓库技巧

  • 背景:

一般仓库文件不大时,我们都可以用这个方法 git clone 仓库,但问题是有时候,在仓库历史的某次 commit 时,有人不小心提交了 1 G 的文件,虽然后面的 commit 中他把这个文件删除了,但是在. git 文件夹中仍然存储着这个文件,所以如果我们克隆仓库这个仓库,会把所有的历史协作记录都 clone 下来,这样整个文件会非常大,其实对于我们直接使用仓库,而不是参与仓库工作的人来说,只要把最近的一次 commit 给 clone 下来就好了。这就好比一个产品有很多个版本,我们只要 clone 最近的一个版本来使用就行了。实现这个功能就需要用到 git clone –depth=1 命令

git clone –depth 1 克隆最近一次 commit

  • 只克隆下包含最近一次 commit 的一个分支:
1
git clone --depth 1 https://github.com/labuladong/fucking-algorithm.git

--depth 用来指定克隆的深度,1 表示克隆最近的一次 commit。这种方法克隆的项目只包含最近的一次 commit 的一个分支,体积很小。
需要将该分支所有的 commit 克隆下来的话,可以用下面的命令:

1
git fetch --unshallow

但会产生另外一个问题,他只会把默认分支 clone 下来,其他远程分支并不在本地,所以这种情况下,需要用如下方法拉取其他分支:

1
2
3
4
$ git clone --depth 1 https://github.com/dogescript/xxxxxxx.git
$ git remote set-branches origin 'remote_branch_name'
$ git fetch --depth 1 origin remote_branch_name
$ git checkout remote_branch_name
  • 只克隆某个指定分支的最近一次 commit
1
git clone --depth 1  --branch english https://github.com/labuladong/fucking-algorithm.git
  • git clone –depth=1 后拉取其他分支的方法

上面提到的 git clone –depth=1 操作只会 clone 一个分支 english,如果我们想把其他远程分支 (如 master) 也克隆到本地,我们需要用下面的命令

1
2
3
4
git clone --depth 1 https://github.com/labuladong/fucking-algorithm.git
git remote set-branches origin 'remote_branch_name'
git fetch --depth 1 origin remote_branch_name
git checkout remote_branch_name

Sparse Checkout 拉取某个目录

Git 基于元数据方式分布式存储文件信息的,它会在每一次 Clone 的时候将所有信息都取回到本地,即相当于在你的机器上生成一个克隆版的版本库。
Git 通过 Sparse Checkout 支持拉取子文件夹,其中一共 5 个步骤,分别进行分析:

1
2
3
4
5
(1)在指定的文件夹下,创建一个空的repository。
(2)获取远程仓库中的所有对象,但不Check out它们到本地,同时将远程Git Server URL加入到Git Config文件中,这个过程会耗时多一点,如果项目比较大。
(3)在Config中允许使用Sparse Checkout模式。
(4)定义要实际检出的文件/文件夹。这是通过在列表中借助“.git/info/sparse-checkout”将他们列出。也支持用感叹号`!`实现反向操作
(5)见证奇迹的时刻,从远程库中拉取你要检出的项目。

如,公司的 ui 图,所有项目都在一起,总共有 7 G 多,新来的同学要全部拉取,那是个灾难:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 初始化一个仓库
git init

# 添加远程url,项目大的化,会很慢
git remote add -f origin git@git.moumentei.com:ddddffe/qiubai_design.git

# 配置支持sparse checkout,在.git/config文件写个配置
git config core.sparseCheckout true

# 添加子文件夹,在.git/info/sparse-checkout添加一条记录
echo "标注与切图/糗百新版/用户教育/截图分享&看图分享" >> .git/info/sparse-checkout

# 拉取
git pull origin master
  • 要 Sparse Checkout 的目录:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
#!/usr/bin/env bash
# 用于配置Sparse Checkou目录

git config core.sparsecheckout true

echo "【要Sparse Checkout的目录】:" $@
for var in "$@"
do
    echo "    目录已配置Sparse Checkout:$var"
    echo ${var} >> .git/info/sparse-checkout
done
echo "【当前的Sparse Checkout配置】:"
#ls -al .git/info/sparse-checkout
cat .git/info/sparse-checkout
#open .git/info/sparse-checkout
git pull origin master

#标注与切图/糗百新版/用户教育/截图分享&看图分享
#标注与切图/糗百新版/单帖页/评论详情排序
#标注与切图/糗百新版/发帖审帖/糗事发帖授权协议
本文由作者按照 CC BY 4.0 进行授权