前言
当你找到 Git-LFS 的时候,多半目的是为了要使用 Github 存储大文件,但是在往下操作之前,需先知道 Git-LFS 不是免费的。
Git-LFS 只提供 1 GB 存储空间,和每月 1 GB 的流量,一旦超额,仓库就会被限制检出。
所以如果你仓库大文件超出这个数,又不愿意付费使用的话,就不需要再考虑 LFS 了。
具体的收费标准可以从
Github Account -> Settings -> Billing & plans
查看。
简介
Github 对大文件有限制,当超过 100M 的时候无法上传。为了解决这个问题,Git-LFS 应运而生。
Git-LFS 即 Git Large File Storage,它是 Git 的一个扩展,当我们通过 LFS 上传大文件到 Github 后,该文件只会在我们的 Github 仓库生成一个指针文件,checkout 的时候也只会对指针文件进行操作。只有在本地以特定命令才能从 Github 重新 checkout 该文件,故而确保了我们的仓库不会过大。
关于 LFS 的更多介绍可见 官方说明
安装
先在系统安装 git-lfs :
- Mac:
brew install git-lfs
- ubuntu:
apt-get install git-lfs
- centos:
yum install git-lfs
再为 git 安装 lfs 扩展:
git lfs install
使用
在一个已经安装 lfs 扩展的 Git 仓库中使用以下命令可追踪大文件:
git lfs track "$FILE_PATTERN"
# 示例: git lfs track "*.exe"
# 注意: *.exe 是大小写敏感的,如果存在 *.EXE 文件是无法匹配的
每跟踪一种类型的大文件,可重复执行一次此命令,该命令会生成一个 .gitattributes
文件,用于描述 Git-LFS 的文件名匹配模板,其内容的每一行形如:
*.exe filter=lfs diff=lfs merge=lfs -text
-text
就是表示这个文件不是文本文件- 其余的就是告诉 Git 在处理 filter、diff、merge 时,把
*.exe
文件通过 LFS 的方式处理
使用 track 命令追踪档案之后,就可以打破 Github 的 100M 限制,把大文件推送到远端仓库上,不过在首次推送的时候,会消耗一些时间。
迁移
这才是比较实用的,因为很多仓库是用着用着才想到要用 lfs 的。。。
对于一个已经用了一段时间的仓库,直接使用 track 命令是无法追踪之前已经提交到仓库的大文件的。
此时需要执行以下命令把本地分支上的匹配文件的提交历史版本都转换为 lfs :
git lfs migrate import --include="$FILE_PATTERN" --everything
# 示例: git lfs migrate import --include="*.exe" --everything
# 注意: 与 track 命令同理,每一种类型的大文件都需重复执行一次此命令
执行该命令后,无论切换到哪个分支,都会出现 .gitattributes
文件,且内容都是一样的。
当然,如果只想更新某个分支,可以使用 git lfs migrate import --include="$FILE_PATTERN" --include-ref=refs/heads/<branch_name>
命令指定。
可以通过
git lfs ls-files
命令查看哪些文件被转换成了 lfs
执行 migrate 迁移命令后,会更改所有已提交的 hash,因此需要使用 force 选项提交,以更新远端仓库:
git push --force
迁移成功后,本地 git 仓库的大小可能并没有变化,主要是因为之前的提交还在,可以按需进行清理:
git reflog expire --expire-unreachable=now --all
git gc --prune=now
拉取
对于其他使用这个仓库的人而言,如果是第一次拉取仓库:
# 只会拉取普通文件,LFS 所追踪的大文件会以指针文件形式拉下来
GIT_LFS_SKIP_SMUDGE=1 git clone $REPO_ADDR
# 根据指针文件,拉取 LFS 所追踪的大文件
git lfs pull
但如果其他人已经使用了这个仓库一段时间,但是该仓库被你用 migrate 命令迁移了,他们再次使用 pull 去远程拉取的时候会失败,此时他们可以使用 pull --allow-unrelated-histories
命令把远程仓库被修改的历史与本地仓库历史做合并,但最好是重新拉取。
恢复
前面已经说过,Git-LFS 只提供 1 GB 存储空间,和每月 1 GB 的流量。
一旦超额,只要检出 LFS 文件就会报错:
batch response: This repository is over its data quota. Account responsible for LFS bandwidth should purchase more data packs to restore access
此时要么每月支付 $5 ,要么就恢复为非 LFS 仓库,步骤如下:
- 如果本地没有备份大文件,先执行
git lfs pull
把大文件拉回来(如果已经超额了,就只能先付费一个月把数据拉回来了) - 在 Github 删除仓库,再重建同名仓库
- 在本地依次执行以下命令,重新推送仓库数据:
rm -rf .git
git init
git add -A
git commit -m "rebuild"
git remote add origin $REPO_ADDR
git push -f -u origin master
重建仓库后,如果有其他人已经使用仓库一段时间了,他们是无法再直接 pull 仓库了。此时他们要么删除本地仓库重新 clone,要么执行以下命令以远端覆盖本地:
git fetch --all
git reset --hard origin/master
小知识
Git-LFS 推送的文件过大,导致推送时间过长,推送过程需要多次输入密码。
此问题可以修改 git 凭据的缓存时间解决:
# Set git to use the credential memory cache
git config --global credential.helper cache
# Set the cache to timeout after 1 hour (setting is in seconds)
git config --global credential.helper 'cache --timeout=3600'
其他系统的修改方式见《Caching your GitHub credentials in Git》