图像应该存储在git存储库中吗?


200

对于使用Git和Github作为版本控制的分布式团队,图像也应该存储在git存储库中吗?

在大多数情况下,图像不会改变。包含它们的文件夹只会随着添加图像的大小而增加。令人担忧的是,随着时间的推移,图像文件夹可能会通过合并大图像或仅合并其中的许多图像而变得很大。

这是最佳做法吗?还有什么其他方法可以共享分布式团队可以轻松访问的项目中所需的二进制文件?


17
当您说“图像”时,我们是在谈论26mb DSLR Raw文件,1mb 3d游戏纹理还是<100k png图标?(我打算回答“取决于”,但我会避免)
布鲁克

2
@布鲁克:我有点假设我们在谈论网站的图标或小型图形元素。您是正确的,游戏纹理,图形设计原始文件或用于文档编辑的精确图形可能是另一回事。
haylem 2011年

6
我个人认为他是指ISO图像,而不是图片。
Mahmoud Hossam

2
它实际上应该用于中小型Web友好图像。令人担忧的是,当我认为应该使用其他一些东西时,一些开发者将开始在其中粘贴每个大型原始图像。
海棉

6
今天读这个问题?在git lfs上查看下面的答案。这可能是您想要的。programmers.stackexchange.com/a/306882/92506
jonnybot

Answers:


188

您的图片是原始作品,还是可以从其他地方恢复(保证?)?他们需要运送从源头构建的软件单元吗?如果它们是原始的,则需要备份。将它们放在版本控制中,如果它们永远不变,则空间损失与备份相同,因此它们是您需要的地方。

是否可以对其进行编辑以意外或有意更改软件的外观?是的-然后必须以某种方式对它们进行版本控制,为什么当您已经有了完善的解决方案时为什么要使用另一种方法。为什么从黑暗时代开始引入“复制并重命名”版本控制?

当图形设计师的MacBook硬盘驱动器去世时,我已经看到了整个项目的原始图稿变得“糟透了”,这全都是因为某个人拥有无限的智慧,决定“二进制文件不属于转速控制范围”,而图形设计师(至少是这个人) )的备份往往不太好。

同样适用于所有符合上述条件的二进制文件。

唯一的原因不是磁盘空间。恐怕以100美元/ TB的价格计算,这种借口太薄了。


44
顺便说一句:互联网不是可靠的来源。如果您是从“ bobsfreestuff.com”下载的图片,那么下周可能会消失了。
mattnz 2011年

16
+1-且应为+ more。版本控制的重点是允许您在过去的某个时间恢复/回滚到任何内容。成为100%的唯一方法是,您可以及时收回当时应有的一切,从而将所有内容置于版本控制之下。那就是源,图像,资源,有用/支持的PDF。哎呀,我什至还放了压缩CD映像。甚至我都知道将VM虚拟机(包括VMDK)放入源代码管理中。似乎极端?2年后保存了我的培根。
quick_now 2011年

3
100%同意。如果图像是软件的一部分,则需要对其进行修订控制。
迪恩·哈丁

14
我不同意的唯一原因是,如果这样做会使您的存储库繁琐而难以复制,以至于开发人员不得不真正想到“我真的想花时间克隆它,还是可以在另一个分支中执行X”。如果发生这种情况,请确保一切很快重新组织起来
Brook

5
+1表示需要部署。如果由于我是新团队成员或其他原因而克隆了您的存储库,则它应该开箱即用。这确实包括使makefile等效文件足够聪明,以便在必要时获取必要的第三方库。
Spencer Rathbun 2012年

66

为什么不呢?:)

是的,存储二进制文件被认为是不好的做法,是的,但是我从不担心图像。

最坏的情况是,如果您有大量货物,请将其存放在其他地方或使用外部组件或扩展程序进行二进制支持。而且,如果图像不会经常更改,那么问题出在哪里?您不会得到很大的肥胖三角洲。而且,如果它们随着时间的流逝而被删除,那么存储历史记录的只是您的服务器,而客户端看不到任何东西。

在我看来,您不必担心-因为您不存储其中的GB。

虽然做的,只是Store“源”的图像:SVGs,乳胶宏,等等,并有通过构建系统生成的最终图像。如果可以的话,那可能更好。如果没有,那就不要打扰。

(话虽这么说,Git可以显示文本文件,但不是用于图片的最佳VCS。如果可以,请给我们提供更多上下文和指标)


有关其他信息,您可能需要查看以下问答:


4
+1用于存储源代码,但是如果他们可以在没有完整版本的情况下进行开发测试,则可能会使其混乱。这也意味着您需要在早上开始工作之前先构建所有图像
TheLQ 2011年

@TheLQ:我想,但是也许您应该有级联的版本,其中您的下游(测试)版本只能依靠上游版本(实际版本)。然后将它们导出到公用文件夹,以供测试人员在本地重用。显然,这意味着需要一些基础架构,但这是我在规模相对较大的团队中进行工作的方式。
haylem 2011年

什么是二进制文件?
Daniel Pendergast 2014年


5
“为什么不呢?” -因为如果您的回购超过2GB,Bitbucket(我也曾在Github上尝试过)会拒绝您的回购。因此,如果您用大量的图像膨胀它们,请准备好托管自己的存储库。
2015年

48

这个问题已经很老了,但是这是在处理Git时遇到的一个常见问题,自从上一个答案以来,在将大型文件存储在Git存储库中的现代解决方案上已有了一些进展。

为了在Git中存储大文件,有以下项目:

  • git-annex-已经存在了一段时间,但坦率地说,它的复杂性阻碍了它的发展。
  • git-media-没有个人经验。似乎也相当复杂。
  • git-fit-尝试创建一个更简单的插件。需要S3存储。虽然我很欣赏这个简单性,但是我对插件的主要关注是它是一个未知数,并且由1个人维护(完整披露,我是目前唯一的其他提交者,并且涉及的问题不多)。
  • git-lfs-虽然我没有广泛使用它,但这似乎是圣杯。它由Github 提供支持,自2015年10月起可在其所有存储库中使用,并将文件管理的复杂性放在存储存储库的站点上。唯一不足的是,这是相当新的,所以超越Github上没有太多的支持,虽然Gitlab也有支持如确实Gitea到位桶已经提到在未来支持

TLDR:如果可以,请使用git-lfs将图像或其他二进制文件存储在git中。


9
很长一段时间以来,我第一次很高兴能向下滚动阅读投票率较低的答案。git lfs正是我想要的,Atlassian甚至在BitBucket Server中添加了对它的支持!如果我能对此投票一百万次,那我会。
jonnybot'2

7
@jonnybot,谢谢。我的回答很晚,所以我没有太多的知名度,但是我自己使用git-lfs之后,它认为这是在git中存储二进制文件的最新解决方案。
詹姆斯·麦克马洪

45

出于“特定原因”提出了整个“不要在源代码管理中存储二进制文件”:如果您具有可编译的源代码,则不存储实际的编译,而仅存储源代码。图像和视觉资产没有“源”,因此在版本控制中对其进行跟踪。


4
有时,视觉资产具有“类似于源代码的东西”,那么最好是自动化创建最终输出的过程,并将源代码仅存储在版本控制中。例如:由SVG文件制成的光栅图形版本,从Sprite表中切出的网站资产。
tanius

正确,这是一个完全公平的论点。
杰森·费瑟辛汉姆

21

我相信使用Git的推荐方法是使用子模块(在Git 1.5.3中引入),该子模块基本上是与主模块相关联的独立存储库。您将图像(和其他二进制资产)存储在子模块中。然后可以根据需要将其与主存储库一起签出或保留。

来自http://book.git-scm.com/5_submodules.html

“ Git的子模块支持允许存储库包含外部项目的签出作为子目录。子模块保持其自身的身份;子模块支持仅存储子模块存储库的位置和提交ID,因此其他克隆包含项目的开发人员(“ “您可以在同一版本中轻松克隆所有子模块。可以对超级项目进行部分检出:您可以告诉Git不克隆任何,部分或全部子模块。”

另外,如果图像不经常更改,尺寸也不是一个重要的问题。您还可以运行命令以修剪/减小大小,例如:

git gc
git gc-aggressive
git prune

7

是的

可以说您发布了软件版本1.0。对于2.0版,您决定重做所有带有阴影的图片。因此,您执行此操作,然后发布2.0。然后,一些正在使用1.0且无法升级到2.0的客户决定他们想要使用另一种语言的程序。他们会给您$ 1G来做,因此您可以肯定。但是在不同的文化中,您的某些图片没有意义,因此您必须进行更改...

如果将图像保留在源代码管理中,这很容易,您可以基于1.0对图像进行更改(包括其他操作),构建,发布。如果您在源代码管理中没有这些图像,那么您将遇到很多困难,因为您将不得不找到旧图像,对其进行更改然后再进行构建。


7

如果它是项目的一部分,则必须在VCS中。如何达到最佳效果可能取决于VCS或组织项目的方式。可能是设计人员的回购协议,而编码人员的回购协议中只有结果,或者只有“图像源”(我曾经有一个仅带有.svg文件的项目,并且图像是通过make / inscape cli生成的)。

但是,如果VCS无法处理或变得无法使用,我会说这不是您工作的正确工具。

到目前为止,我在git中为Web项目放置“通常”数量的图形(模型,概念和页面图形)没有问题。


5

您是否应该将图像存储在SCM中:是。毫无疑问。

您是否应该将图像存储在git中:这将变得更加棘手。

git非常适合文本文件,但是就其本质而言,二进制文件并不是太热。克隆或推送时,传输的数据大小会出现问题,.git目录会增加,并且合并可能会引起混乱(即,如何合并2张图像!)

一种答案是使用子模块,因为这意味着您的项目和图像之间的链接会更弱-因此,您不必像管理图像一样将其作为源代码的一部分来管理,而仍可对其进行控制,而不必担心将它们分支-假设子项目只是一个“平坦”的数据存储库,在通常的开发过程中不会经历相同的变动。

另一个答案是将它们放置在不同的项目中,从不分支它,并确保提交该项目的每个人都将其立即向上游推送-永远不要让2个人更改文件的相同版本-您会发现这是最困难的git方面不是针对此类非分布式工作流而设计的。您必须使用老式的通信方法来使用此规则。

第三个答案是将它们完全放在另一个SCM中,以便更好地处理图像。


0

除了@haylem的答案外,请注意大小在其中起着很大的作用。取决于VCS,它可能无法处理大量图像。当克隆或大型推送开始耗费整夜时,这太晚了,因为所有映像都已经在您的存储库中。

规划大图和未来的增长。您不想花两年时间来从事这个项目,而又不想“回购,也许回购规模太大了 ”。


1
您的答案有点无关紧要,因为问题是特定于git的。您是否知道大小是否对git存储库起很大(或任何因素)的作用?
yannis 2011年

@Yannis必须错过第一句话... AFAIK,对于较大的存储库,git更好,但是大小问题仍然存在,因为巨大的克隆或推送是一个问题
TheLQ 2011年

如果碰巧成为问题,使用GIT可以很容易地重新排列存储库并创建部分克隆等。不要将几十年前的修订控制工具与今天的历史控制混为一谈。
mattnz

0

我绝对同意在技术上和经济上存储它们是可行的。我会问“这些图像是运输产品的一部分还是运输产品的内容的一部分?” 不是说您不能在GIT(或任何其他VCS)中存储内容,而是对于单独的VCS来说是一个单独的问题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.