Git 大文件存储 (LFS)
管理音频、视频和图形文件等大文件一直是 Git 的缺点之一。一般建议是不要让 Git 仓库大于 1GB 以保持性能。
Git LFS 跟踪的文件会显示一个图标,以指示文件是存储为 blob 还是 LFS 指针。
如何工作
Git LFS 客户端通过 HTTPS 与 GitLab 服务器通信。它使用 HTTP 基本身份验证来授权客户端请求。请求被授权后,Git LFS 客户端接收指令,从哪里获取或从哪里推送大文件。
要求
- 必须在项目设置下启用 Git LFS
- Git LFS 客户端 1.0.1 及以上版本
已知限制
- 不支持 Git LFS v1 原始 API,因为它在 LFS 开发早期被弃用。
- 当 SSH 设置为远程时,Git LFS 对象仍然通过 HTTPS。
- 任何 Git LFS 请求都要求提供 HTTPS 凭据,因此建议使用良好的 Git 凭据存储。
- Git LFS 始终假定 HTTPS,因此如果您在 HTTP 上拥有 GitLab 服务器,则必须手动将 URL 添加到 Git 配置。
- 群组 wiki 不支持 Git LFS。
使用 Git LFS
让我们来看看当您需要使用 Git LFS 将大文件检入 Git 仓库时的工作流程。例如,如果您想上传一个非常大的文件并将其检入您的 Git 仓库:
git clone git@gitlab.example.com:group/project.git
git lfs install # initialize the Git LFS project
git lfs track "*.iso" # select the file extensions that you want to treat as large files
将要跟踪的文件扩展名标记为 LFS 对象后,您可以照常使用 Git,而无需重新执行命令来跟踪具有相同扩展名的文件:
cp ~/tmp/debian.iso ./ # copy a large file into the current directory
git add . # add the large file to the project
git commit -am "Added Debian iso" # commit the file meta data
git push origin main # sync the git repo and large file to the GitLab server
确保 Git 跟踪了 .gitattributes
。否则 Git LFS 对于克隆项目的人无法正常工作:
git add .gitattributes
克隆仓库的工作方式与以前相同。Git 会自动检测 LFS 跟踪的文件并通过 HTTP 克隆它们。如果您使用 SSH URL 执行 git clone
命令,则必须输入您的凭据以进行 HTTP 身份验证。
git clone git@gitlab.example.com:group/project.git
如果您已经克隆了仓库,并且想要获取远端仓库上的最新 LFS 对象,例如来自 origin 的分支:
git lfs fetch origin main
确保您的文件没有在 .gitignore
中列出,否则它们会被 Git 忽略并且不会被推送到远端仓库。
从 LFS 中删除对象
从 LFS 中删除对象:
- 使用
git filter-repo
从仓库中删除对象。 - 删除您从
.gitattributes
文件中删除的对象的相关 LFS 行并提交这些更改。
项目档案中的 LFS 对象
在 13.5 版本之前,项目源下载将包含 Git LFS 指针而不是实际对象。例如,LFS 指针如下所示:
version https://git-lfs.github.com/spec/v1
oid sha256:3ea5dd307f195f449f0e08234183b82e92c3d5f4cff11c2a6bb014f9e0de12aa
size 177735
在 13.5 及更高版本中,这些指针被转换为上传的 LFS 对象。
故障排查
遇到应该是指针但不是指针的 n
个文件
此错误表明该文件(或多个文件)应由 LFS 跟踪,但由于某种原因,仓库未将它们作为 LFS 进行跟踪。此问题可能是此错误的一个潜在原因:通过 Web 界面上传时文件未使用 LFS 跟踪
要解决此问题,请迁移受影响的文件(或多个文件)并将其推回仓库:
-
将文件迁移到 LFS:
git lfs migrate import --yes --no-rewrite "<your-file>"
-
推送回您的仓库:
git push
1.(可选)清理您的 .git
文件夹:
git reflog expire --expire-unreachable=now --all
git gc --prune=now
error: Repository or object not found
出现此错误的原因有两个:
- 您无权访问某些 LFS 对象
检查您是否有权推送到项目或从项目中获取。
- 不允许项目访问 LFS 对象
您尝试推送到项目或从项目中获取的 LFS 对象不再可供项目使用。可能该对象已从服务器中删除。
- 本地 Git 存储库正在使用已弃用的 LFS API
Invalid status for <url>
: 501
Git LFS 将故障记录到日志文件中。 要查看此日志文件,请在项目目录中:
git lfs logs last
如果显示状态 error 501
,是因为:
-
项目设置中未启用 Git LFS。检查您的项目设置并启用 Git LFS。
-
GitLab 服务器上未启用 Git LFS 支持。请与您的管理员核实为什么未在服务器上启用 Git LFS。
-
Git LFS 客户端版本不受 GitLab 服务器支持。使用
git lfs version
检查 Git LFS 版本。使用git lfs -l
检查项目的 Git 配置以获取废弃 API 的痕迹。如果在配置中设置了batch = false
,请删除该行并尝试更新您的 Git LFS 客户端。仅支持 1.0.1 及更新版本。
getsockopt: connection refused
如果您将 LFS 对象推送到项目并收到这样的错误,则 LFS 客户端正在尝试通过 HTTPS 访问极狐GitLab。但是,您的实例是通过 HTTP 提供的:
Post <URL>/info/lfs/objects/batch: dial tcp IP: getsockopt: connection refused
当 Git 配置中未设置 lfsurl
时,默认情况下 Git LFS 使用 HTTPS 连接会导致这种情况。
为了防止这种情况发生,请在项目 Git 配置中设置 LFS URL:
git config --add lfs.url "http://gitlab.example.com/group/project.git/info/lfs"
推送对象时始终需要凭据
Git LFS 在每次推送每个对象时使用 HTTP 基本身份验证对用户进行身份验证,因此需要用户 HTTPS 凭据。
默认情况下,Git 支持记住您使用的每个仓库的凭据。Git 凭据手册页中对此进行了描述。
例如,您可以告诉 Git 在您期望推送对象的一段时间内记住密码:
git config --global credential.helper 'cache --timeout=3600'
这会记住一个小时的凭据,之后 Git 操作需要重新进行身份验证。
如果您使用的是 OS X,您可以使用 osxkeychain
来存储和加密您的凭据。
对于 Windows,您可以使用 wincred
或 Microsoft 的 Git Credential Manager for Windows。
有关存储用户凭据的各种方法的更多详细信息,请参见 Git 凭据存储文档。
推送时缺少 LFS 对象
GitLab 检查文件以检测推送时的 LFS 指针。如果检测到 LFS 指针,会尝试验证这些文件是否已存在于 LFS 中。
验证 LFS 是否安装在本地并考虑使用 git lfs push --all
手动推送。
如果您在极狐GitLab 之外存储 LFS 文件,您可以通过使用项目 API 设置 lfs_enabled: false
来禁用项目上的 LFS。
在外部托管 LFS 对象
通过使用 git config -f .lfsconfig lfs.url https://example.com/<project>.git/info/lfs
设置自定义 LFS URL,可以在外部托管 LFS 对象。
如果您使用像 Nexus 仓库这样的设备来存储 LFS 数据,您可能会选择这样做。如果您选择使用外部 LFS 存储,系统无法验证 LFS 对象。如果您启用了极狐GitLab LFS 支持,则推送将失败。
为了阻止推送失败,可以在项目设置中禁用 LFS 支持,这也会禁用 GitLab LFS 增值(验证 LFS 对象,LFS 的 UI 集成)。