阅读
- 第 1 部分:什么是 Git?
- 第 2 部分:Git 入门
- 第 3 部分:创建你的第一个 Git 仓库
- 第 4 部分: 如何在 Git 中恢复旧版本的文件
- 第 5 部分: 3 个 Git 图形化工具
- 第 6 部分: 如何构建你自己的 Git 服务器
- 第 7 部分: 如何使用 Git 管理二进制大对象
在本系列的前六篇文章中,我们学习了如何使用 Git 管理文本文件的版本控制。但是二进制文件呢?Git 具有处理二进制大对象(如多媒体文件)的扩展,因此今天我们将学习如何使用 Git 管理二进制资产。
大家似乎都同意一件事,那就是 Git 不太适合大型二进制大对象。请记住,二进制大对象与大型文本文件不同;你可以毫无问题地在大型文本文件上使用 Git,但 Git 对不可渗透的二进制文件无能为力,只能将其视为一个大的黑色盒子并按原样提交。
假设你为一个激动人心的新第一人称益智游戏制作了一个复杂的 3D 模型,并以二进制格式保存,结果得到一个 1 吉字节的文件。你执行一次 git commit
,为你的仓库历史记录添加了一个吉字节。稍后,你给模型换了一个发型并提交了你的更新;Git 无法区分头发、头部或模型的其余部分,因此你又提交了一个吉字节。然后你更改了模型的眼睛颜色并提交了那个小的更改:又一个吉字节。这是一个模型,只是随意做了几个小的更改就占用了三个吉字节。将这种情况扩展到游戏中的所有资产,你就会遇到严重的问题。
与 .obj
格式这样的文本文件形成对比。一次提交存储所有内容,就像另一个模型一样,但是 .obj
文件是一系列描述模型顶点的纯文本行。如果你修改模型并将其保存回 .obj
,Git 可以逐行读取这两个文件,创建更改的差异,并处理相对较小的提交。模型变得越精细,提交就越小,这是一个标准的 Git 用例。它是一个大文件,但它使用一种覆盖或稀疏存储方法来构建数据当前状态的完整图像。
然而,并非所有东西都以纯文本形式工作,而且如今每个人都想使用 Git。因此需要一种解决方案,并且已经出现了几种解决方案。
Git Large File Storage (LFS) 是 GitHub 的一个开源项目,最初是 git-media 的一个分支。Git-media 和 git-annex 是 Git 的扩展,旨在管理大型文件。它们是解决同一问题的两种不同方法,并且各有优势。以下不是这些项目本身的官方声明,但根据我的经验,它们的独特之处在于
-
Git-annex
倾向于分布式模型;你和你的用户创建仓库,每个仓库都有一个本地.git/annex
目录,用于存储大文件。附件会定期同步,以便所有用户在需要时都可以访问所有资产。除非使用annex-cost
另行配置,否则git-annex
优先使用本地存储而不是异地存储。 -
Git-portal
也是分布式的,并且像 Git-annex 一样,可以选择同步到中央位置。它使用你可能已经安装的常用实用程序(特别是 Bash、Git、rsync)。 -
Git-LFS
是一个集中式模型,是通用资产的仓库。你告诉 Git-LFS 你的大文件存储在哪里,无论是硬盘驱动器、服务器还是云存储服务,并且你项目中的每个用户都将该位置视为大型资产的中央主位置。
git-portal
Git-portal 使用标准的 UNIX 工具(如 Bash、Git 本身以及可选的 rsync)为 Git 提供简化的 blob 管理。它将大型二进制文件复制到本地或远程存储,并用符号链接替换它们,你可以将这些符号链接与项目的其余文件一起提交。
Git-portal 很简单,但有时会有点手动(例如,它没有自动垃圾回收)。它非常适合需要管理通常不适合 Git 管理的大型文件,但又不想学习全新系统的用户。Git-portal 模仿 Git 本身,因此学习曲线非常小。
你可以从 Gitlab 上的项目页面安装 Git-portal。
所有 Git-portal 命令都镜像 Git 本身。要在项目中使用 Git-portal
$ git-portal init
添加文件
$ git-portal add bigfile.png
一旦文件“通过门户发送”(在项目的术语中),你与 Git 的交互与往常完全相同。你像往常一样添加文件,相对来说不会注意到其中一些文件实际上是指向 _portal 目录的符号链接。
_portal 目录中的所有内容(Git 完全忽略该目录)都可以单独备份到你喜欢的任何类型的存储中,无论是 USB 驱动器还是远程服务器。由于 Git-portal 提供了一些 Git 钩子(由特定的 Git 操作(如 push 或 pull)触发的自动化脚本),你甚至可以设置一个特殊的 Git 远程条目,以便你的 _portal 目录与远程位置自动同步
$ git remote add _portal alice@myserver.com:/home/alice/umbrella.git/_portal
Git-portal 具有简单且原生 Linux 系统的优势。凭借相当少的常用实用程序和只需记住的几个额外命令,你可以管理大型项目依赖项,甚至在协作者之间共享它们。Git-portal 已用于媒体项目、独立视频游戏和游戏博客,以管理从小的启动画面图像到大型 PDF 甚至更大的 3D 模型的所有内容。
git-annex
git-annex
具有略有不同的工作流程,并且默认使用本地仓库,但基本思想是相同的。你应该能够从你的发行版仓库安装 git-annex
,或者你可以根据需要从网站获取它。与 git-media
一样,任何使用 git-annex
的用户都必须在其机器上安装它。
初始设置比 git-media
更简单。要在你的服务器上创建裸仓库,请运行以下命令,并替换你自己的路径
$ git init --bare --shared /opt/jupiter.git
然后将其克隆到你的本地计算机上,并将其标记为 git-annex
位置
$ git clone seth@example.com:/opt/jupiter.clone
Cloning into 'jupiter.clone'... warning: You appear to have cloned
an empty repository. Checking connectivity... done.
$ git annex init "seth workstation" init seth workstation ok
与其使用过滤器来识别媒体资产或大型文件,不如使用 git annex
命令来配置哪些内容被归类为大型文件
$ git annex add bigblobfile.flac
add bigblobfile.flac (checksum) ok
(Recording state in Git...)
提交照常进行
$ git commit -m 'added flac source for sound fx'
但是推送是不同的,因为 git annex
使用自己的分支来跟踪资产。你进行的第一次推送可能需要 -u
选项,具体取决于你如何管理你的仓库
$ git push -u origin master git-annex
To seth@example.com:/opt/jupiter.git
* [new branch] master -> master
* [new branch] git-annex -> git-annex
与 git-media
一样,正常的 git push
不会 将你的资产复制到服务器,它只会发送有关媒体的信息。当你准备好与团队的其余成员共享你的资产时,运行 sync 命令
$ git annex sync --content
如果其他人已将资产共享到服务器并且你需要拉取它们,git annex sync
将提示你的本地检出拉取你机器上不存在但在服务器上存在的资产。
Git annex 是一个经过微调的解决方案,灵活且用户友好。它功能强大且经过充分测试。
git-lfs
git-lfs
是用 Go 编写的,你可以从源代码安装它,也可以作为可下载的二进制文件安装。说明在 网站 上。每个想要使用 git-lfs
的用户都需要安装它,但它是跨平台的,因此通常不会造成问题。
安装 git-lfs
后,你可以设置你希望 Git 忽略而 Git-LFS 管理的文件类型。例如,要让 Git-LFS 跟踪所有 .png 文件
$ git lfs track "*.png"
每次你为 Git-LFS 跟踪添加文件类型时,你都必须添加然后提交文件 .gitattributes
$ git add .gitattributes
$ git commit -m "LFS track *.png"
当你暂存这些类型的文件时,该文件将被复制到 .git/lfs
。
Git-LFS 是 Github 的一个项目,并且与 Github 的基础设施紧密相关。如果你想运行允许 Git-LFS 集成的 Git 服务器,你可以研究 Git-LFS 服务器规范(也是用 Go 编写的)并实现 API。
git-portal
和 git-annex
都很灵活,并且可以使用本地仓库而不是服务器,因此它们对于管理私有本地项目也同样有用。
大型文件和 Git
虽然 Git 是为文本文件设计的,但这并不意味着仅仅因为你有二进制资产就不能使用它。有很多很好的解决方案可以帮助你管理大型文件。如果你想使用 Git,真的没有太多借口不使用它,所以今天就试试吧!
8 条评论