Git LFS 使用指南

如果你在命令行用 git push 添加或更新 $>$ 50MB 的文件,你会收到一个 warning,不过你仍然可以正常 push。但如果 $>$ 100MB 的时候就无法 push 了。如果你是在浏览器要上传文件的话,这个限制更为严重,不能超过 25MB,这是 GitHub 对仓库的限制。Git LFS 就是用于解决这个问题1

下面几个场景不需要用

  1. 文件大小没有超过限制当然就没有必要用了
  2. 如果是要分发二进制文件(比如 *.exe)等,此时直接用 GitHub 提供的 release 功能就好了

使用 Git LFS 之后,在仓库中存储的其实是对大文件的引用,可以理解为指针。而真正的大文件托管在 Git LFS 的服务器上。GitHub 给不同用户的提供的存储空间不一样,免费用户和 Pro 用户都是 2 GB,而如果是企业用户则会高点2

当我们用 Git LFS 追踪某个大文件(比如 foo.zip)之后,可以看到 .gitattributes 发生了改变

text

foo.zip filter=lfs diff=lfs merge=lfs -text

这一行体现了很多信息

  • foo.zip,这是 Git LFS 正在追踪的大文件符合的模式,说是模式是因为用 Git LFS 追踪大文件的时候可以用通配符,那么这里就会是通配符的形式
  • filter=lfs:用 Git LFS 的方式对待被追踪的大文件
  • diff=lfs:用 Git LFS 的方式对待被追踪的大文件
  • -text,表示不会将这个大文件看成是文本文件

如果用的是 Mac,那么用 Homebrew 就可以很方便安装

sh

$ brew install git-lfs
$ git lfs install
# 如果输出为 Git LFS initialized. 就是正常安装好了

我们可以通过如下的不同方式让 Git LFS 追踪一个大文件或者是一堆大文件

  • 指定大文件后缀名——git lfs track "*.filetype",即批量追踪 *.filetype 文件
  • 指定某个目录下的所有文件——git lfs track "directory/*",即批量追踪 directory 里面的文件
  • 指定某个具体大文件——git lfs track "path/to/file"

sh

$ mkdir <repo>
$ cd <repo>
$ git init
$ git lfs track "*.zip" # 比如 *.zip

# git lfs track 会修改 .gitattributes 文件的内容,可以验证一下
# > cat .gitattributes
# *.zip filter=lfs diff=lfs merge=lfs -text

下面假定有一个远程仓库供我们使用

sh

$ git add .
$ git commit -m "<msg>"
$ git push -u origin main

此时命令行会显示

text

uploading LFS objects

此时只是简单使用 git lfs track ... 追踪大文件是不够的,因为这个大文件已经存在 Git 仓库的历史记录里,这会导致 Git 仓库无法变小。正确的方法是使用 git lfs migrate,将 Git 历史的大文件变成 Git LFS 追踪的对象3

比如可以用 --include=,Git LFS 会自动根据我们指定的模式进行选择。下面的 --include="*.txt 的意思就是选中 Git 仓库历史的 txt 文件

技巧
可以用 man git-lfs-migrate 查看更多信息

bash

$ git lfs migrate import --include="*.txt"

# 让远程仓库也改过来
$ git push --force

bash

$ git lfs untrack "*.filetype"
$ git rm --cached "*.filetype"
  1. 查看当前 Git LFS 正在追踪的文件类型——git lfs track
  2. 查看当前 Git LFS 正在追踪哪些文件——git lfs ls-file