Git-LFS 的使用和迁移笔记


前言

当你找到 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

参考文档


文章作者: EXP
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 EXP !
 上一篇
Github Desktop 代理设置 Github Desktop 代理设置
在国内使用 Github Desktop 速度太慢,而且本身不提供代理设置入口,故作此记录。 Windows 只需修改文件 %HOMEPATH%/.gitconfig, Mac / Linux 只需修改文件 ~/.gitconfig, 在其
下一篇 
利用 kOps 在 AWS 部署 k8s 集群 利用 kOps 在 AWS 部署 k8s 集群
kOps 是用于在 AWS 上搭建 k8s 集群的 oob 工具,通过配置授权,它可以直接调度 AWS 上的资源,全自动创建并管理一个高可用的 k8s 集群
2021-02-08
  目录