Git LFS

Git LFS 是 Github 开发的一个 Git 的扩展,用于实现 Git 对大文件的支持。


使用目的

有些用户,尤其是游戏行业以及媒体行业人员可能会遇到一个问题,那就是随着提交的文件越来越多,项目 越来越大,Git的响应速度越来越慢,更烦人的是,在提交到远程仓库的最后一刻,系统可能会提示用户此次 提交被拒绝,原因是提交的文件太大,触发平台额度限制(无论是哪个平台),相信很多人在这一刻是崩溃的。

Git LFS(Git Large File Storage),即Git大文件存储技术。

在Git仓库中,对于非文本文件,如各种多媒体文件,软件制品文件,二进制文件等等,这些文件 往往体积比较大,使用Git直接管理会导致仓库的体积迅速膨胀,进而导致Git的许多操作变慢,同 时也影响仓库上传到远程端。

Git LFS相当于Git的一种插件式增强工具,简单讲,它是在Git仓库使用这些文件的 指针代替 实际文件, 而把实际文件存储在远程端LFS服务器,同时在本地仓库中实时追踪这些文件的变动。

principle

原理

根据 Git LFS官方帮助文档描述:

Git LFS是基于Git的 .gitattributs 配置文件的特性,用 smudge过滤器基于 指针文件寻找大文件内 容, 用 clean过滤器在对大文件改动时,创建指针文件的新版本。同时还用 pre-push钩子将大文件上传 到Git LFS服务器, 即在 git-push时, 如果提交中包含被LFS跟踪的大文件,pre-push钩子会检测 到,并执行上传Git LFS服务器的动作。

因此,如果一个仓库中包含LFS内容,但是在推送时不想推送这类文件,只要加上 --no-verify选项就行,即:

$ git push --no-verify

--no-verify选项告诉 git push完全跳过 pre-push钩子。

前面提到被LFS管理的文件,本地仓库中保存的内容实际上是指针文件,其格式类似于下面这样:

$ git show HEAD:2.svg

version https://git-lfs.github.com/spec/v1
oid sha256:158213f90f8b27012034c6f58db63e1861b12aa122d98910de311bf1cb1e50a0
size 14651
(END)

version表示LFS的版本

oid表示文件对象的唯一hash值

size表示文件的大小

安装

注意:以下安装以及命令使用演示,均是基于Linux中命令行的方式进行,Windows上的图像界面 操作,由于时间关系,暂不涉及。

安装依赖: Git >=1.8.5

Linux 系统:

curl -s https://packagecloud.io/install/repositories/github/git-lfs/script.deb.sh | sudo bash
sudo apt-get install git-lfs

https://packagecloud.io/github/git-lfs/install#bash

其它操作系统上的安装,见官方安装文档:

https://github.com/git-lfs/git-lfs#installing

用法

  • 在Git仓库中为仓库设置相关配置:

    $ git lfs install
    

    Tips:

    这个命令会自动改变Git配置文件 .gitconfig,而且是全局性质的,会自动在配置文件中增加如下配置:

    [filter "lfs"]

    clean = git-lfs clean -- %f

    smudge = git-lfs smudge -- %f

    process = git-lfs filter-process

    required = true

  • 选择要用LFS追踪的文件:

    $ git lfs track "*.svg"
    # 或者具体到某个文件
    $ git lfs track "2.png"
    $ git lfs track "example.lfs"
    

    Tips:

    这个命令会更改仓库中的 .gitattributes配置文件(如果之前不存在这个文件,则会自动新建):

    查看如下:

    $ cat .gitattributes

    *.svg filter=lfs diff=lfs merge=lfs -text

    *.png filter=lfs diff=lfs merge=lfs -text

  • 查看正在被LFS追踪的文件:

    $ git lfs ls-files
    9a3c7dae41 * 1.png
    d61cf5835a * 2.png
    158213f90f * 3.svg
    

    git add file 之后文件才可能被追踪,也才能查看得到

  • 取消LFS追踪的文件:

    $ git lfs untrack "1.png"
    
  • 保存并提交配置:

    $ git add .gitattributes
    $ git commit -m "add .gitattributes"
    

用法总结

安装Git LFS之后,只需三步,即可在仓库中配置LFS功能,即:

#step 1
$ git lfs install

#step 2
$ git lfs track files

# step 3
$ git add .gitattributes

实际上,由于第一步是全局配置,所以执行一次即可,后续有其它仓库需要使用LFS,则不需要再次执行,除非中途取消了LFS配置。

Tips:

运行 git lfs uninstall 即可取消LFS的全局配置

使用LFS管理历史大文件

如果一个仓库中原来已经提交了一些大文件,此时即使运行 git lfs track也不会有效的。

为了将仓库中现存的大文件应用到LFS,需要用 git lfs migrate导入到LFS中:

$ git lfs migrate import --include-ref=master --include="biger.zip"
migrate: override changes in your working copy?  All uncommitted changes will be lost! [y/N] y
migrate: changes in your working copy will be overridden ...
migrate: Sorting commits: ..., done.
migrate: Rewriting commits: 100% (11/11), done.
  master        f9be3c554e9010ea5e0e23a6a0c6e53dca6c23b0 -> 53d5e655fe7cfd985f75384b92ac5414ad2ff394
migrate: Updating refs: ..., done.
migrate: checkout: ..., done.

--include-ref 选项指定导入的分支

如果向应用到所有分支,则使用--everything选项

--include 选项指定要导入的文件。可以使用通配符,批量导入。

上述操作会改写提交历史,如果不想改写历史,则使用 --no-rewrite选项,并提供新的commit信息:

$ git lfs migrate import --no-rewrite -m "lfs import"

将本地历史提交中的文件纳入到LFS管理后,如果重改了历史,再次推送代码时,需要使用强制推送。

这里选择改变提交历史,所以还需要使用 --force强制推送:

$ git push origin master --force

Enter passphrase for key '/home/git/.ssh/id_ed25519':
Locking support detected on remote "origin". Consider enabling it with:
  $ git config lfs.https://gitee.com/hightest/lfs-demo.git/info/lfs.locksverify true
Uploading LFS objects: 100% (8/8), 419 MB | 0 B/s, done.
Enumerating objects: 38, done.
Counting objects: 100% (38/38), done.
Delta compression using up to 6 threads
Compressing objects: 100% (37/37), done.
Writing objects: 100% (38/38), 136.26 MiB | 943.00 KiB/s, done.
Total 38 (delta 12), reused 10 (delta 0), pack-reused 0
remote: Powered by GITEE.COM [GNK-6.1]
To gitee.com:hightest/lfs-demo.git
 + cefd169...53d5e65 master -> master (forced update)

至此,已经将历史提交中的大文件迁移到远程LFS服务器,本地Git仓库,只保留这个大文件的指针 文件,所以推送也不会再触发额度限制。推送成功之后,远程仓库就与本地保存一致,它只管理这个大文件的指针文件。

帮助命令

直接获得有关特定命令的帮助:

$ git lfs help <subcommand>

官方文档有该工具的命令参考和规范。wiki 上还有一个常见问题解答,它回答了一些常见问题。

如果您对如何使用 Git LFS 有疑问,不确定某事,或者正在寻找其他人关于最佳实践或用例提示的输入,请随时 开始讨论

您可以随时打开问题,其中一位核心团队成员会回复您。

LFS Test Server

LFS Test Server 是一个实现Git LFS API的示例服务器。它旨在用于测试Git LFS客户端,并未处于生产就绪状态。

LFS Test Server 是用 Go 编写的,预编译的二进制文件可用于 Mac、Windows、Linux 和 FreeBSD。

自建 LFS Server 请参考: LFS Test Server

安装

使用 Go 安装程序:

$ go install github.com/github/lfs-test-server
# or
$ go install github.com/github/lfs-test-server@latest

从源代码安装,请使用 Go 工具:

$ go get github.com/github/lfs-test-server
$ go build

运行

默认情况下,运行二进制文件将启动 LFS 服务器localhost:8080。可以通过环境变量配置的东西很少:

LFS_LISTEN      # The address:port the server listens on, default: "tcp://:8080"
LFS_HOST        # The host used when the server generates URLs, default: "localhost:8080"
LFS_METADB      # The database file the server uses to store meta information, default: "lfs.db"
LFS_CONTENTPATH # The path where LFS files are store, default: "lfs-content"
LFS_ADMINUSER   # An administrator username, default: not set
LFS_ADMINPASS   # An administrator password, default: not set
LFS_CERT        # Certificate file for tls
LFS_KEY         # tls key
LFS_SCHEME      # set to 'https' to override default http
LFS_USETUS      # set to 'true' to enable tusd (tus.io) resumable upload server; tusd must be on PATH, installed separately
LFS_TUSHOST     # The host used to start the tusd upload server, default "localhost:1080"

如果设置了LFS_ADMINUSERLFS_ADMINPASS变量,则可以通过 访问基本的管理界面 http://$LFS_HOST/mgmt。在这里您可以添加和删除用户,这必须在您可以将服务器与客户端一起使用之前完成。如果未设置这些变量中的任何一个(这是默认设置),则禁用管理界面。

要将 LFS 测试服务器与 Git LFS 客户端一起使用,请在存储库的.gitconfig文件中对其进行配置:

[lfs]
  url = "http://localhost:8080/"

HTTPS:

注意:如果将 https 与自签名证书一起使用,也会在客户端 repo 中禁用证书检查。

[lfs]
  url = "https://localhost:8080/"
[http]
  sslverify = false

示例用法

生成密钥对

openssl req -x509 -sha256 -nodes -days 2100 -newkey rsa:2048 -keyout mine.key -out mine.crt

创建一个运行脚步

#!/bin/bash

set -eu
set -o pipefail


LFS_LISTEN="tcp://:9999"
LFS_HOST="127.0.0.1:9999"
LFS_CONTENTPATH="content"
LFS_ADMINUSER="<cool admin user name>"
LFS_ADMINPASS="<better admin password>"
LFS_CERT="mine.crt"
LFS_KEY="mine.key"
LFS_SCHEME="https"

export LFS_LISTEN LFS_HOST LFS_CONTENTPATH LFS_ADMINUSER LFS_ADMINPASS LFS_CERT LFS_KEY LFS_SCHEME

./lfs-test-server

在浏览器打开管理页面:https://localhost:9999/mgmt

总结

Git LFS是一个易于安装、易于配置,使用高效的Git拓展工具,它能有效的管理仓库中的大文件, 避免仓库体积过大,影响项目管理效率。同时,Gitee平台对Git LFS功能有很好的支持,再加上灵 活的空间配额管理,让企业实现自动扩容,方便的解决了企业在项目开发中遇到的仓库大文件问题。

参考链接

Git Large File Storage

Git LFS Wiki

gitattributes

Git LFS 操作指南