Git实战笔记(二) 大文件管理

1,249 阅读4分钟

在这篇文章中,你将会看到:Git LFS 的简单介绍、原理解析、下载安装和基本使用方法


1、简单介绍

在开发过程中,我们可能需要对一些体积较大的二进制文件(例如图片、音视频、设计稿等)进行版本管理

但对这些大文件的任何细微修改,都会产生巨大的提交量,导致仓库体积迅速膨胀,最终使得仓库难以使用

且克隆仓库更要浪费大量的时间,这是因为在克隆过程中需要将仓库的整个历史记录传输到客户端

幸运的是,一个由 Github 开发的 Git 拓展 (Git Large File Storage, Git LFS) 很好地解决了这一个问题


2、原理解析

Git LFS 是怎么解决问题的呢?

实际上 Git LFS 也并非变魔术般处理大文件,它只是把负担转移给远程服务器,使本地仓库能保持相对精简

首先,它将大文件存储在主仓库之外的空间,而在主仓库只保留轻量级指针,这样可以大大减小仓库的体积

其次,大文件会在 checkout 时下载,而不是 clone 或 fetch 时下载,这样只需下载所需版本而非历史版本


以下是更详细的解析(参考 Atlassian Blog,Atlassian 是 Git LFS 的主要开发者之一)

  1. 当你向仓库添加一个文件时 ( git add ),Git LFS 会用指针替换其内容,并将真正的内容存储在本地 LFS 缓存(本地 LFS 缓存位于仓库的 .git/lfs/objects 目录中)
  2. 当你向远端推送新的提交时 ( git push ),在推送中新的提交所引用的 Git LFS 文件将会直接从本地 LFS 缓存传输到绑定 Git 仓库的远端 LFS 存储(即文件内容将会直接从本地缓存传输到远端存储)
  3. 当你检出一个包含 Git LFS 指针的提交时 ( git checkout ),指针文件会替换为本地 LFS 缓存中的文件,或从远端 LFS 存储下载

3、下载安装

以下是 Windows 用户的下载方法,其它系统的用户可能略有不同,具体请参考 这里

  1. 下载安装包(这是 v2.13.2 版本,也可以在官网上找最新的下载)
  2. 运行安装包,安装 Git LFS
  3. 在终端执行 git lfs install,初始 Git LFS

至此,Git LFS 已经安装完成,下面让我们来看看怎么使用 Git LFS 来管理大文件吧


4、基本使用

常见命令一览:

  • git lfs track <文件模式>    :将指定的文件模式加入 Git LFS 管理
  • git lfs untrack <文件模式>:将指定的文件模式移出 Git LFS 管理
  • git lfs track  :查看当前 Git LFS 管理的匹配列表
  • git lfs status:查看当前 Git LFS 管理的对象状态
  • git lfs clone <远程仓库地址>:克隆远程仓库

(1)创建一个新的 Git LFS 仓库

在执行 git init 初始化一个 Git 仓库后,还需要运行 git lfs install

这会在仓库中安装一个 pre-push 钩子,这个钩子将会在执行 git push 时传输 LFS 文件到服务器


(2)克隆一个现有 Git LFS 仓库

我们依然可以使用 git clone 命令克隆一个仓库,Git 会检出默认分支,并逐一下载所有相关的 LFS 文件

但更好的方法应该是显式使用 git lfs clone 命令以获取更好的性能

这是因为该命令不是一次下载一个 LFS 文件,而是等检出完成后批量下载,这充分利用了并行下载的优势


(3)跟踪文件

我们可以使用 git lfs track <文件模式> 命令将指定的文件模式加入 Git LFS 管理

在运行上述命令后,会发现目录下出现一个 .gitattributes 文件,该文件记录着被管理内容的相关信息

Git LFS 会自动创建并更新 .gitattributes 文件,但你需要手动将该文件的变更提交到仓库

如果不再需要管理某种文件模式,可以使用 git lfs untrack <文件模式> 命令将其移出 Git LFS 管理


(4)查看状态

有两种方式可以查看 Git LFS 管理内容的状态

一是通过 git lfs track   查看当前 Git LFS 管理的匹配列表

二是通过 git lfs status 查看当前 Git LFS 管理的对象状态


5、其它补充

Github 已经禁止上传超过 100M 的大文件,如果你在本地已经提交了这样的文件,该怎么办呢?

一个有效的解决方案是借助 git filter-repo 工具将所有历史提交中不符合要求的文件剔除

首先通过 pip 安装 git filter-repo

pip install git-filter-repo

然后就可以利用这个工具剔除所有历史提交中大于 100M 的文件

git filter-repo --strip-blobs-bigger-than 100M

这里仅仅是抛砖引玉哈,关于 git filter-repo 其它更具体的用法可以参见 官方文档