关山难越,谁悲失路之人;萍水相逢,尽是他乡之客。
百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程教程 > 技术文章 > 正文

Git 系列(七):使用 Git 管理二进制大对象

guanshanw 2023-10-07 11:53 16 浏览 0 评论

-- Seth Kenlon

本文导航

  • -git-media36%

  • -git-annex70%

通过这系列的前六篇文章,我们已经学会使用 Git 来对文本文件进行版本控制的管理。我们不禁要问,还有二进制文件呢,也可进行进行版本控制吗?答案是肯定的,Git 已经有了可以处理像多媒体文件这样的二进制大对象块(blob)的扩展。因此,今天我们会学习使用 Git 来管理所谓的二进制资产。

似乎大家都认可的事就是 Git 对于大的二进制对象文件支持得不好。要记住,二进制大对象与大文本文件是不同的。虽然 Git 对大型的文本文件版本控制毫无问题,但是对于不透明的二进制文件起不了多大作用,只能把它当作一个大的实体黑盒来提交。

设想这样的场景,有一个另人兴奋的第一人称解密游戏,您正在为它制作复杂的 3D 建模,源文件是以二进制格式保存的,最后生成一个 1GB 大小的的文件。您提交过一次,在 Git 源仓库历史中有一个 1GB 大小的新增提交。随后,您修改了下模型人物的头发造型,然后提交更新,因为 Git 并不能把头发从头部及模型中其余的部分离开来,所以您只能又提交 1GB 的量。接着,您改变了模型的眼睛颜色,提交这部分更新:又是 GB 级的提交量。对一个模型的一些微小修改,就会导致三个 GB 级的提交量。对于想对一个游戏所有资源进行版本控制这样的规模,这是个严重的问题。

不同的是如 .obj这种格式的文本文件,和其它类型文件一样,都是一个提交就存储所有更新修改状态,不同的是.obj文件是一系列描述模型的纯文本行。如果您修改了该模型并保存回.obj文件,Git 可以逐行读取这两个文件,然后创建一个差异版本,得到一个相当小的提交。模型越精细,提交就越小,这就是标准的 Git 用例。虽然文件本身很大,但 Git 使用覆盖或稀疏存储的方法来构建当前数据使用状态的完整描述。

然而,不是所有的都是纯文本的,但都要使用 Git,所以需要解决方案,并且已经出现几个了。

OSTree[1] 开始是作为 GNOME 项目出现的,旨在管理操作系统的二进制文件。它不适用于这里,所以我直接跳过。

Git 大文件存储[2](LFS) 是放在 GitHub 上的一个开源项目,是从 git-media 项目中分支出来的。git-media[3] 和git-annex[4] 是 Git 用于管理大文件的扩展。它们是对同一问题的两种不同的解决方案,各有优点。虽然它们都不是官方的项目,但在我看来,每个都有独到之处:

  • git-media 是集中模式,有一个公共资产的存储库。你可以告诉 git-media 大文件需要存储的位置,是在硬盘、服务器还是在云存储服务器,项目中的每个用户都将该位置视为大型文件的中心主存储位置。

  • git-annex 侧重于分布模式。用户各自创建存储库,每个存储库都有一个存储大文件的本地目录 .git/annex。这些 annex 会定期同步,只要有需要,每个用户都可以访问到所有的资源。除非通过 annex-cost 特别配置,否则 git-annex 优先使用本地存储,再使用外部存储。

对于这些,我已经在生产中使用了 git-media 和 git-annex,那么下面会向你们概述其工作原理。

git-media

git-media 是使用 Ruby 语言开发的,所以首先要安装 gem(LCTT 译注:Gem 是基于 Ruby 的一些开发工具包)。安装说明在其网站[5]上。想使用 git-meida 的用户都需要安装它,因为 gem 是跨平台的工具,所以在各平台都适用。

安装完 git-media 后,你需要设置一些 Git 的配置选项。在每台机器上只需要配置一次。

  1. $ git config filter.media.clean "git-media filter-clean"

  2. $ git config filter.media.smudge "git-media filter-smudge"

在要使用 git-media 的每个存储库中,设置一个属性以将刚刚创建的过滤器结合到要您分类为“媒体media”的文件类型里。别被这种术语混淆。一个更好的术语是“资产”,因为“媒体”通常的意思是音频、视频和照片,但您也可以很容易地将 3D 模型,烘焙和纹理等归类为媒体。

例如:

  1. $ echo "*.mp4 filter=media -crlf" >> .gitattributes

  2. $ echo "*.mkv filter=media -crlf" >> .gitattributes

  3. $ echo "*.wav filter=media -crlf" >> .gitattributes

  4. $ echo "*.flac filter=media -crlf" >> .gitattributes

  5. $ echo "*.kra filter=media -crlf" >> .gitattributes

当您要暂存stage这些类型的文件时,文件会被复制到 .git/media目录。

假设在服务器已经有了一个 Git 源仓库,最后一步就告诉源仓库“母舰”所在的位置,也就是,当媒体文件被推送给所有用户共享时,媒体文件将会存储的位置。这在仓库的 .git/config文件中设置,请替换成您的用户名、主机和路径:

  1. [git-media]

  2. transport = scp

  3. autodownload = false #默认为 true,拉取资源

  4. scpuser = seth

  5. scphost = example.com

  6. scppath = /opt/jupiter.git

如果您的服务器上 SSH 设置比较复杂,例如使用了非标准端口或非默认 SSH 密钥文件的路径,请使用 .ssh/config为主机设置默认配置。

git-media 的使用和普通文件一样,可以把普通文件和 blob 文件一样对待,一样进行 commit 操作。操作流程中唯一的不同就是,在某些时候,您应该将您的资产(或称媒体)同步到共享存储库中。

当要为团队发布资产或自己备份资料时,请使用如下命令:

  1. $ git media sync

要用一个变更后的版本替换 git-media 中的文件时(例如,一个已经美声过的音频文件,或者一个已经完成的遮罩绘画,或者一个已经被颜色分级的视频文件),您必须明确的告诉 Git 更新该媒体。这将覆盖 git-media 不会复制远程已经存在的文件的默认设置:

  1. $ git update-index --really-refresh

当您团队的其他成员(或是您本人,在其它机器上)克隆本仓库时,如果没有在 .git/config中把autodownload选项设置为true的话,默认是不会下载资源的。但 git-media 的一个同步命令git media sync可解决所有问题。

git-annex

git-annex 的处理流程略微的有些不同,默认是使用本地仓库的,但基本的思想都一样。您可以从你的发行版的软件仓库中安装 git-annex,或者根据需要从该网站上下载安装。与 git-media 一样,任何使用 git-annex 的用户都必须在其机器上安装它。

其初始化设置比 git-media 都简单。运行如下命令,其中替换成您的路径,就可以在您的服务器上创建好裸存储库:

  1. $ git init --bare --shared /opt/jupiter.git

然后克隆到本地计算机,把它标记为 git-annex 的初始路径:

  1. $ git clone seth@example.com:/opt/jupiter.clone

  2. Cloning into 'jupiter.clone'...

  3. warning: You appear to have clonedan empty repository.

  4. Checking connectivity... done.

  5. $ git annex init "seth workstation"

  6. init seth workstation ok

不要使用过滤器来区分媒体资源或大文件,您可以使用 git annex命令来配置归类大文件:

  1. $ git annex add bigblobfile.flac

  2. add bigblobfile.flac

  3. (checksum) ok

  4. (Recording state in Git...)

跟普通文件一样进行提交操作:

  1. $ git commit -m 'added flac source for sound fx'

但是推送操作是不同的,因为 git annex使用自己的分支来跟踪资产。您首次推送可能需要-u选项,具体取决于您如何管理您的存储库:

  1. $ git push -u origin master git-annex

  2. To seth@example.com:/opt/jupiter.git

  3. * [new branch] master -> master

  4. * [new branch] git-annex -> git-annex

和 git-media 一样,普通的 git push命令是不会拷贝资料到服务器的,仅仅只是发送了相关的消息,要真正共享文件,需要运行同步命令:

  1. $ git annex sync --content

如果别人已经提交了共享资源,您需要拉取它们,git annex sync命令将提示您要在本地检出你本机没有,但在服务器上存在的资源。

git-media 和 git-annex 都非常灵活,都可以使用本地存储库来代替服务器,所以它们也常用于管理私有的本地项目。

Git 是一个非常强大和扩展性非常强的系统应用软件,我们应该毫不犹豫的使用它。现在就开始试试吧!

作者:Seth Kenlon[6] 译者:runningwater校对:wxy

本文由 LCTT[7] 原创编译,Linux中国荣誉推出

推荐文章

相关推荐

七条简单命令让您玩转Git
七条简单命令让您玩转Git

凭借着出色的协作能力、快速部署效果与代码构建辅助作用,Git已经得到越来越多企业用户的青睐。除了用于开发商业及消费级应用之外,众多科学及政府机构也开始尝试使用这...

2023-10-07 12:14 guanshanw

基本完整的关于Git分支branch的操作
基本完整的关于Git分支branch的操作

Git使用背景项目中要用到dev或者其他分支开发完代码,需要将该分支合并到master的需求操作步骤下面以dev名称为lex为分支名为例来操作一遍客户端操作:...

2023-10-07 12:14 guanshanw

Git 进阶(合并与变基)
Git 进阶(合并与变基)

在Git中整合来自不同分支的修改主要有两种方法:合并(merge)以及变基(rebase)合并(merge)merge流程图merge的原理是找到这两个分...

2023-10-07 12:13 guanshanw

Git学习笔记 003 Git进阶功能 part5 合并(第一部分)

合并(merge)是很常用的操作。尤其是一个庞大的很多人参与开发的企业级应用。一般会设定一个主分支,和多个副分支。在副分支开发完成后,合并到主分支中。始终保持主分支是一个完整的,稳定的最新状态的分支。...

非标题党,三张图帮你理解git merge和git rebase的区别
非标题党,三张图帮你理解git merge和git rebase的区别

初始场景:基于正常的开发分支修改几个小bug,然后在合并到开发分支上。gitmergegitcheckoutfeaturegitmergeho...

2023-10-07 12:13 guanshanw

git 初次使用(01)
git 初次使用(01)

先从github上克隆代码下来:使用vscode克隆代码如下图,填写上github仓库地址:vscode有时候克隆代码速度比较慢,可以用命令行方式克隆gitc...

2023-10-07 12:12 guanshanw

Git 远程操作

4.Git远程操作命令说明gitremote远程版本库操作gitfetch从远程获取版本库gitpull下载远程代码并合并gitpush上传远程代码并合并4.1远程版本库操作gitre...

Git常用命令-总结
Git常用命令-总结

创建git用户$gitconfig--globaluser.name"YourName"$gitconfig--globaluser.em...

2023-10-07 12:12 guanshanw

git中删除从别人clone下来项目的git信息,并修改为自己的分支

如果你从别人的Git存储库中克隆了一个项目,并想要删除与该存储库相关的Git信息,并将其修改为你自己的分支,则可以执行以下步骤:使用gitclone命令克隆存储库:gitclone<u...

git系列-回滚和放弃本地修改

回滚历史提交就是reset的功能。这种情况是已经提交远程仓库,需要回滚到之前的提交。gitreset--hardcommitId//注:强制提交后,当前版本后面的提交版本将会删掉!gi...

GIT使用小技巧大全
GIT使用小技巧大全

在大型软件工程的开发过程中,版本控制是无法绕过去的;目前来说,最火的版本控制软件就是GIT了。早两年SVN比较火,不过被大神linus喷了几次后,就日落西山了,...

2023-10-07 12:11 guanshanw

git相关命令-上
git相关命令-上

这些命令都是看了文档后,个人觉得比较有用的一些,展示给大家。回到远程仓库的状态抛弃本地所有的修改,回到远程仓库的状态。gitfetch--all&...

2023-10-07 12:10 guanshanw

Git命令行接口:掌握Git的必备技能
Git命令行接口:掌握Git的必备技能

Git是一款强大的分布式版本控制工具,它支持命令行界面操作。熟练掌握Git命令行接口,是开发者使用Git的必备技能之一。在这篇文章中,我们将介绍Git命令行接口...

2023-10-07 12:10 guanshanw

Git命令详解
Git命令详解

相信各位小伙伴们应该都对git有一些了解,毕竟作为代码管理的神器,就算不是IT行业的小伙伴肯定也或多或少的听说过一些。今天就来和小伙伴们分享一下自己总结的常用命...

2023-10-07 12:10 guanshanw

工作7年收集到的git命令
工作7年收集到的git命令

概念git中的术语解释:仓库也叫版本库(repository)stage:暂存区,add后会存到暂存区,commit后提交到版本库git安装linux...

2023-10-07 12:10 guanshanw

取消回复欢迎 发表评论: