Git 专门为源代码版本控制而设计,因此很少被主要从事纯文本工作的项目和行业所接受。然而,异步工作流程的优势很有吸引力,尤其是在越来越多的行业将严肃的计算与严肃的艺术事业相结合的情况下,包括网页设计、视觉效果、视频游戏、出版、货币设计(是的,这是一个真正的行业)、教育……等等。
在本系列 Git 14 周年纪念的前期文章中,我们分享了六种鲜为人知的 Git 用法。在最后一篇文章中,我们将了解将 Git 的优势带入多媒体文件管理的软件。
使用 Git 管理多媒体文件的问题
Git 不适用于非文本文件似乎是常识,但挑战假设总是没错的。这是一个使用 Git 复制照片文件的示例
$ du -hs
108K .
$ cp ~/photos/dandelion.tif .
$ git add dandelion.tif
$ git commit -m 'added a photo'
[master (root-commit) fa6caa7] two photos
1 file changed, 0 insertions(+), 0 deletions(-)
create mode 100644 dandelion.tif
$ du -hs
1.8M .
到目前为止,一切正常;将 1.8MB 的照片添加到目录会导致目录大小为 1.8MB。那么,让我们尝试删除该文件
$ git rm dandelion.tif
$ git commit -m 'deleted a photo'
$ du -hs
828K .
您可以在此处看到问题:在提交后删除一个大文件会使存储库的大小增加大约原始空白状态的八倍(从 108K 增加到 828K)。您可以执行测试以获得更好的平均值,但这个简单的演示与我的经验一致。提交非文本文件的成本最初很小,但是项目保持活动状态的时间越长,人们对静态内容进行的更改越多,这些零碎的成本就开始累积起来。当 Git 存储库变得非常大时,主要成本通常是速度。执行拉取和推送操作的时间从喝一口咖啡的时间变成怀疑您的计算机是否被踢出网络的时间。
静态内容导致 Git 大小增长的原因是,基于文本的格式允许 Git 仅拉出已更改的部分。栅格图像和音乐文件对于 Git 来说,就像您查看 .png 或 .wav 文件中包含的二进制数据一样,毫无意义。因此,即使一张照片与下一张照片只有一个像素发生变化,Git 也只会获取所有数据并制作一个新的副本。
Git-portal
实际上,许多多媒体项目不需要或不想跟踪媒体的历史记录。项目的媒体部分往往具有与项目的文本或代码部分不同的生命周期。媒体资产通常朝着一个方向发展:图片从铅笔草图开始,朝着其作为数字绘画的目标前进,并且,即使文本回滚到早期版本,艺术也会继续向前发展。媒体很少绑定到项目的特定版本。例外情况通常是反映数据集的图形——通常是表格或图表——可以使用基于文本的格式(如 SVG)完成。
因此,在许多涉及媒体和文本(无论是叙事散文还是代码)的项目中,只要在版本控制周期之外有一个供艺术家发挥的场所,Git 都是文件管理的可接受解决方案。

启用它的一个简单方法是 Git-portal,这是一个配备 Git 钩子的 Bash 脚本,可将您的资产文件移动到 Git 范围之外的目录,并用符号链接替换它们。Git 提交符号链接(有时称为别名或快捷方式),这些符号链接非常小,因此您提交的只是文本文件和代表您的媒体资产的任何符号链接。由于替换文件是符号链接,因此您的项目继续按预期运行,因为您的本地计算机遵循符号链接到它们的“真实”副本。Git-portal 在用符号链接交换文件时维护项目的目录结构,因此如果您认为 Git-portal 不适合您的项目,或者您需要构建没有符号链接的项目版本(例如,用于分发),则很容易逆转该过程。
Git-portal 还允许通过 rsync 远程同步资产,因此您可以设置远程存储位置作为集中授权源。
Git-portal 非常适合多媒体项目,包括视频游戏和桌面游戏设计、具有大型 3D 模型渲染和纹理的虚拟现实项目、带有图形和 .odt 导出的书籍、协作博客网站、音乐项目等等。艺术家在其应用程序中执行版本控制(以图形世界的图层和音乐世界的音轨的形式)并不少见,因此 Git 对多媒体项目文件本身没有任何添加。Git 的强大功能被用于艺术项目的其他部分(散文和叙事、项目管理、字幕文件、演职员表、营销文案、文档等等),而结构化远程备份的强大功能则被艺术家所利用。
安装 Git-portal
Git-portal 的 RPM 包位于 https://klaatu.fedorapeople.org/git-portal,您可以下载并安装。
或者,您可以从 GitLab 上的主页手动安装 Git-portal。它只是一个 Bash 脚本和一些 Git 钩子(也是 Bash 脚本),但它需要一个快速构建过程,以便它知道将自身安装在哪里
$ git clone https://gitlab.com/slackermedia/git-portal.git git-portal.clone
$ cd git-portal.clone
$ ./configure
$ make
$ sudo make install
使用 Git-portal
Git-portal 与 Git 一起使用。这意味着,与 Git 的所有大文件扩展一样,有一些额外的步骤需要记住。但是您只需要在处理媒体资产时才需要 Git-portal,因此除非您已经习惯于将大文件与文本文件同等对待(这对于 Git 用户来说很少见),否则很容易记住。您必须执行一个设置步骤才能在项目中使用 Git-portal
$ mkdir bigproject.git
$ cd !$
$ git init
$ git portal init
Git-portal 的 init 函数在您的 Git 存储库中创建一个 _portal 目录,并将其添加到您的 .gitignore 文件中。
在日常例程中使用 Git-portal 可以与 Git 无缝集成。一个很好的例子是基于 MIDI 的音乐项目:音乐工作站生成的项目文件是基于文本的,但 MIDI 文件是二进制数据
$ ls -1
_portal
song.1.qtr
song.qtr
song-Track_1-1.mid
song-Track_1-3.mid
song-Track_2-1.mid
$ git add song*qtr
$ git portal song-Track*mid
$ git add song-Track*mid
如果您查看 _portal 目录,您会找到原始 MIDI 文件。它们位置的文件是 _portal 的符号链接,这使得音乐工作站可以按预期工作
$ ls -lG
[...] _portal/
[...] song.1.qtr
[...] song.qtr
[...] song-Track_1-1.mid -> _portal/song-Track_1-1.mid*
[...] song-Track_1-3.mid -> _portal/song-Track_1-3.mid*
[...] song-Track_2-1.mid -> _portal/song-Track_2-1.mid*
与 Git 一样,您也可以添加文件目录
$ cp -r ~/synth-presets/yoshimi .
$ git portal add yoshimi
Directories cannot go through the portal. Sending files instead.
$ ls -lG _portal/yoshimi
[...] yoshimi.stat -> ../_portal/yoshimi/yoshimi.stat*
删除操作按预期工作,但是当删除 _portal 中的内容时,您应该使用 git-portal rm 而不是 git rm。使用 Git-portal 可确保文件从 _portal 中删除
$ ls
_portal/ song.qtr song-Track_1-3.mid@ yoshimi/
song.1.qtr song-Track_1-1.mid@ song-Track_2-1.mid@
$ git portal rm song-Track_1-3.mid
rm 'song-Track_1-3.mid'
$ ls _portal/
song-Track_1-1.mid* song-Track_2-1.mid* yoshimi/
如果您忘记使用 Git-portal,则必须手动删除 portal 文件
$ git portal rm song-Track_1-1.mid
rm 'song-Track_1-1.mid'
$ ls _portal/
song-Track_1-1.mid* song-Track_2-1.mid* yoshimi/
$ trash _portal/song-Track_1-1.mid
Git-portal 的唯一其他功能是列出所有当前的符号链接,并查找任何可能已损坏的符号链接,这有时会在项目目录中移动文件时发生
$ mkdir foo
$ mv yoshimi foo
$ git portal status
bigproject.git/song-Track_2-1.mid: symbolic link to _portal/song-Track_2-1.mid
bigproject.git/foo/yoshimi/yoshimi.stat: broken symbolic link to ../_portal/yoshimi/yoshimi.stat
如果您将 Git-portal 用于个人项目并维护自己的备份,那么从技术上讲,这就是您需要了解的关于 Git-portal 的全部内容。如果您想添加协作者,或者您希望 Git-portal 以(或多或少)Git 的方式管理备份,您可以添加远程仓库。
添加 Git-portal 远程仓库
为 Git-portal 添加远程位置是通过 Git 现有的远程功能完成的。Git-portal 实现了 Git 钩子,这些脚本隐藏在您的存储库的 .git 目录中,用于查看您的远程仓库中任何以 _portal 开头的仓库。如果找到一个,它会尝试 rsync 到远程位置并同步文件。每当您执行 Git 推送或 Git 合并(或拉取,实际上只是获取和自动合并)时,Git-portal 都会执行此操作。
如果您只克隆了 Git 存储库,那么您可能从未自己添加过远程仓库。这是一个标准的 Git 过程
$ git remote add origin git@gitdawg.com:seth/bigproject.git
$ git remote -v
origin git@gitdawg.com:seth/bigproject.git (fetch)
origin git@gitdawg.com:seth/bigproject.git (push)
名称 origin 是您的主 Git 存储库的流行约定,因此将其用于您的 Git 数据是有意义的。但是,您的 Git-portal 数据是单独存储的,因此您必须创建第二个远程仓库来告诉 Git-portal 推送到哪里以及从哪里拉取。根据您的 Git 主机,您可能需要单独的服务器,因为千兆字节的媒体资产不太可能被空间有限的 Git 主机接受。或者,也许您位于一台服务器上,该服务器只允许您访问您的 Git 存储库,而不能访问外部存储目录
$ git remote add _portal seth@example.com:/home/seth/git/bigproject_portal
$ git remote -v
origin git@gitdawg.com:seth/bigproject.git (fetch)
origin git@gitdawg.com:seth/bigproject.git (push)
_portal seth@example.com:/home/seth/git/bigproject_portal (fetch)
_portal seth@example.com:/home/seth/git/bigproject_portal (push)
您可能不希望在您的服务器上为所有用户提供个人帐户,而且您不必这样做。要提供对托管存储库的大文件资产的服务器的访问权限,您可以运行 Git 前端,例如 Gitolite,或者您可以使用 rrsync(即,受限 rsync)。
现在,您可以将您的 Git 数据推送到您的远程 Git 存储库,并将您的 Git-portal 数据推送到您的远程 portal
$ git push origin HEAD
master destination detected
Syncing _portal content...
sending incremental file list
sent 9,305 bytes received 18 bytes 1,695.09 bytes/sec
total size is 60,358,015 speedup is 6,474.10
Syncing _portal content to example.com:/home/seth/git/bigproject_portal
如果您安装了 Git-portal 并配置了 _portal 远程仓库,您的 _portal 目录将同步,从服务器获取新内容并在每次推送时发送新内容。虽然您不必执行 Git 提交和推送来与服务器同步(用户可以直接使用 rsync),但我发现要求提交艺术更改很有用。它将艺术家及其数字资产整合到工作流程的其余部分,并提供有关项目进度和速度的有用元数据。
其他选项
如果 Git-portal 对您来说太简单,则还有其他选项可用于使用 Git 管理大文件。Git Large File Storage (LFS) 是一个已废弃项目 git-media 的分支,由 GitHub 维护和支持。它需要特殊的命令(例如 git lfs track 以保护大文件不被 Git 跟踪),并且需要用户管理 .gitattributes 文件以更新存储库中哪些文件由 LFS 跟踪。它仅支持 HTTP 和 HTTPS 远程仓库用于大文件,因此您的 LFS 服务器必须配置为允许用户通过 HTTP 而不是 SSH 或 rsync 进行身份验证。
比 LFS 更灵活的选项是 git-annex,您可以在我关于 在 Git 中管理二进制 blob 的文章中了解更多信息(忽略关于已弃用的 git-media 的部分,因为其以前的灵活性不适用于其后继者 Git LFS)。Git-annex 是一个灵活而优雅的解决方案,具有用于在存储库中添加、删除和移动大文件的详细系统。由于它灵活且功能强大,因此有很多新命令和规则需要学习,因此请查看其 文档。
但是,如果您的需求很简单,并且您喜欢使用现有技术来完成简单而明显的任务的解决方案,那么 Git-portal 可能是适合这项工作的工具。
评论已关闭。