274

For a distributed team that uses Git and GitHub as version control, should images also be stored in the git repository?

The images in question are small/medium-sized web-friendly images. For the most part, the images won't be changed. The folder containing them will only grow in size as images are added. A concern is that the image folder may grow to a large size over time by combination of large images or a lot of images.

Is this considered a best practice? What other alternatives are there to sharing binary files needed in projects that a distributed team can easily access?

1

10 Answers 10

234

Are your images original work or can they be recovered (guaranteed?) from elsewhere? Are they needed to ship a software unit built from source? If they are original, they need backing up. Put them in your revision control, if they never change, the space penalty is the same as a backup, and they are where you need them.

Can they be edited to change the appearance of the software, accidentally or intentionally? Yes - then they MUST be revision controlled somehow, why use another way when you have a perfect solution already. Why introduce "copy and rename" version control from the dark ages?

I have seen an entire project's original artwork go "poof" when the graphics designer's MacBook hard drive died, all because someone, with infinite wisdom, decided that "binaries don't belong in rev control", and graphics designers (at least this one) don't tend to be good with backups.

Same applies to any and all binary files that fit the above criteria.

The only reason not to is disk space. I am afraid at $100/terabyte, that excuse is wearing a bit thin.

12
  • 64
    BTW : The Internet is NOT a reliable source. If you downloaded an image from "bobsfreestuff.com", it probably will not be there next week.
    – mattnz
    Commented Jun 2, 2011 at 1:59
  • 25
    +1 - and should be +more. The point of version control is to allow you to recover / roll back to stuff, whatever the stuff might be, AT SOME PAST TIME. The only way to be 100% that you can get back what was supposed to be at that point in time it to put EVERYTHING under version control. Thats source, images, resouces, helpfull/supporting PDFs. Heck, I even put Zipped CD images in. I have even been known to put a VM virtual machine (including the VMDK) into source control. Seems extreme? Saved my bacon 2 years later. Commented Jun 2, 2011 at 4:06
  • 6
    100% agree. If images are part of the software, they need to be revision controlled. Commented Jun 2, 2011 at 8:44
  • 22
    The only reason I would disagree would be if it made your repo cumbersome to clone to the point where developers had to actually think "do I really want to take the time to clone this, or can I just do X in this other branch". If this occurs make sure things get re-organized very quickly
    – Brook
    Commented Jun 2, 2011 at 13:29
  • 8
    +1 for the point about needing it for deploy. If I clone your repo, because I'm a new team member or something, then it should work out of the box. This does include having a makefile equivalent clever enough to get necessary 3rd party libraries if necessary. Commented Mar 6, 2012 at 20:14
84

This question is pretty old but this is a common question that comes up when dealing with Git and there has some progress on modern solutions to storing large files in a Git repo since the last answer.

For storing large files in Git there are the following projects:

  • git-lfs - While I haven't used this extensively it appears to be the holy grail. It's backed by Github and is available on all their repos as of October 2015 and puts the complexity of file management on site storing your repos. Only downside is that this is fairly new, so beyond Github there isn't much support, though Gitlab also has support, as does Gitea, and Bitbucket has alluded to support in the future.
  • git-annex - This has been around for awhile but frankly it's complexity gets in the way.
  • git-media - No personal experience with this one. Seems fairly complex as well.
  • git-fit - An attempt to create a simpler plugin. Requires S3 storage. While I appreciate the simplicity my main concern with plugin is that it's fairly unknown and maintained by 1 individual (full disclosure, I am the only other committer at this time and it was for a trivial issue).
  • git-fat - Another, low-dependency approach.

TLDR: if you can, use git-lfs to store images or other binary files in git.

3
  • 11
    For the first time in a long while, I am so glad I scrolled down to read lower-voted answers. git lfs is precisely what I want, and Atlassian's even adding support for it to BitBucket Server! If I could upvote this a million times, I would.
    – jonnybot
    Commented Feb 4, 2016 at 20:54
  • 8
    @jonnybot, thanks. I was a late answer so I haven't gotten a lot of visibility but after using git-lfs myself it think it's the best current solution for storing binary files in git. Commented Feb 9, 2016 at 22:52
  • github supports lfs, but they charge extra for it, which doesn't exactly encourage using it when not forced to do so (i.e when your files are under the size limit to be stored normally). Commented Feb 13, 2023 at 12:44
81

Why the hell not? :)

Storing binaries is considered bad practice, yes, but I never worried too much about images.

Worst case, if you have tons, store them somewhere else or use externals or an extension for binary support. And if the images won't be changed that often, then where's the problem? You won't get a big fat delta. And if they get removed over time, it's only your server that suffers a bit from storing the history, but clients won't see a thing.

In my opinion, you shouldn't worry about it - granted you don't store GBs of those.

What you could do though, is only store "source" images: SVGs, LaTeX macros, etc... and have the final images generated by your build system. That's probably even better, if you can. If not, then don't bother.

(All that being said, Git shines for text files, but is not the best VCS for pictures. Give us more context and metrics if you can)


For additional information, you may want to look at these Q&As:

13
  • 4
    +1 for storing the source, but if they can do development testing without a full build then that might mess it up. That also means you would need to build all the images before starting work in the morning
    – TheLQ
    Commented Jun 2, 2011 at 1:56
  • 1
    @DantheMan: en.wikipedia.org/wiki/Binary_file
    – haylem
    Commented Jul 1, 2014 at 9:31
  • 12
    "Why the hell not?" - because if your repo exceeds 2GB, Bitbucket (and I just tried it with Github too) will reject your repo. So be prepared to host your own repos if you bloat them with tons of images.
    – Jez
    Commented Sep 3, 2015 at 7:41
  • 3
    @Jez: "Worst case, if you have tons, store them somewhere else or use externals or an extension for binary support." and "you shouldn't worry about it - granted you don't store GBs of those." kinda covered that :) Obviously if you start storing a lot of binary data, it's a bad idea. For most small projects, or medium projects where images will be created once and are unlikely to change much for the lifetime of the project, it's acceptable. Still not really a fan though, but that beats having a complicated build setup if you need them. My preference is always text-based image sources though.
    – haylem
    Commented Sep 7, 2015 at 13:23
  • 1
    +1 for the suggestion on SVGs et al. It was not the answer I was looking for, but the answer I needed :-) Commented Jun 19, 2019 at 7:39
60

The whole "don't store binaries in source control" is set forth for a specific reason: If you have source code that compiles, don't store the actual compilation, but just the source code. Images and visual assets do not have a "source," so they should be tracked in version control.

2
  • 11
    Sometimes, visual assets have "something like a source", and then it's a good idea to automate the process of creating the final output and only store the source in version control. Examples: raster graphic versions made from SVG files, website assets cut out from a sprite sheet.
    – tanius
    Commented Mar 20, 2018 at 21:45
  • Correct, that's an entirely fair argument.
    – Jason
    Commented Dec 11, 2018 at 19:10
28

I believe the recommended way with Git is to use a sub-module (introduced in Git 1.5.3) which is basically a separate repository that is associated with the main one. You store your images (and other binary assets) in the sub-module. This can then be checked-out with the main repository or left, depending on what is required.

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

"Git's submodule support allows a repository to contain, as a subdirectory, a checkout of an external project. Submodules maintain their own identity; the submodule support just stores the submodule repository location and commit ID, so other developers who clone the containing project ("superproject") can easily clone all the submodules at the same revision. Partial checkouts of the superproject are possible: you can tell Git to clone none, some or all of the submodules."

Also, size shouldn't be a significant issue if the images don't change often. You can also run commands to prune/reduce size, such as:

git gc
git gc-aggressive
git prune
8

If it is part of the Project, it has to be in the VCS. How to achieve this best may depend on the VCS, or how you organize a Project. Maybe a repo for the designers, and only the results in the coder's repo, or only the 'Image sources' (i once had a project with a only a .svg file, and the images where generated via make/inscape cli).

But, if a VCS cannot handle that, or becomes unusuable, i would say, that it not the right tool for your job.

So far, i had no problems with putting 'usual' amounts of graphics (mockups, concepts, and page graphics) for web projects in git.

8

Should you store your images in a SCM? Yes. Without any doubt.

Should you store your images in git specifically? This gets more tricky.

git is very good with text files, but by its very nature isn't too hot with binaries. You will have issues with the size of the data transferred when you clone or push, your .git directories will grow, and you could get in a right mess with merging (ie how do you merge 2 images!)

One answer is to use submodules, as this means the link between your project and the images will be weaker - so you won't have to manage the images as if they were part of your source, yet still keeping them controlled, and not having worries with branching them - assuming the subproject is just a 'flat' repository of data that doesn't go through the same churn during the usual development process.

The other answer is to put them in a different project, never branch it, and ensure that everyone who commits to that project pushes it upstream immediately - never let 2 people change the same version of the file - you'll find this the most difficult aspect as git isn't designed for such a non-distributed workflow. You'll have to use old-fashioned communication methods to enfore this rule.

A third answer is to put them in a different SCM entirely that is better geared to working with images.

7

Yes.

Lets say you release software version 1.0. For version 2.0 you decide to redo all the pictures to be with shadows. So you do this, and release 2.0. Then some customer who is using 1.0 and cannot upgrade to 2.0 decides they want the program in another language. They give you $1G to do it, so you say sure. But in a different culture, some of your pictures do not make sense, so you have to change them...

If you would keep your images in source control, this is easy, based on 1.0 you make changes to images (among other things), build, release. If you did not have these in source control, you would have a much harder time, since you would have to find the old images, change them, and then build.

0

Adding to @haylem's answer, note that size plays a large factor in this. Depending on the VCS it might not work well with tons of images. When clones or large pushes starting taking all night then its really too late as all the images are already in your repository.

Plan for large pictures and future growth. You don't want to get two years into this project and have a "oh crap, maybe the repo is a little too big."

3
  • 1
    Your answer is somewhat irrelevant, as the question is specific to git. Do you happen to know if size plays a large (or any) factor for git repositories?
    – yannis
    Commented Jun 2, 2011 at 2:02
  • @Yannis Must of missed that first sentence... AFAIK, git is better with larger repositories but the size issue is still relevant as gargantuan clones or pushes are an issue
    – TheLQ
    Commented Jun 2, 2011 at 2:42
  • 1
    With GIT is trivially easy to rearrange repositories and create partial clones etc, if this happens to become a problem. Don't confuse the historical molasses of revision control tools from decades ago with those of today.
    – mattnz
    Commented Jun 2, 2011 at 3:43
0

I definitely agree that technically and economically storing them is feasible. Question I would as is "are these images part of the shipping product or part of the content of a shipping product?" Not that you can't store content in GIT (or any other VCS) but that it is a separate problem for a separate VCS.

Not the answer you're looking for? Browse other questions tagged or ask your own question.