6

I'm developing mobile apps (iPhone, Android, and Blackberry) and recently converted from SVN to Git.

In SVN after I do a release, I tag the relevant branch/revision to ensure its state is preserved and then I add a directory to this tag and put in the released binary and also (for iPhone) the debug symbols files for that exact build (for symbolificating any crash reports later on). The files don't need to be versioned, but it's a convenient place to store the historic artifacts along with the code to ensure they are backed-up (SVN has a backup policy whereas the builds on my CI server don't).

I'm trying to figure out the best equivalent in Git. Probably the closest thing would be to create a new branch, add the binary files, tag it, and delete the branch. However, I'm wondering if there are any better ways of doing this?

Ideally I'd like to create a tag and then attach the binaries as unversioned files to the tag. This way, they don't actually appear in the source tree but they are there in the repository, associated with the tag, for retrieval as necessary by anyone with access to the repository. Is there anything equivalent to this in Git?

jhabbott
  • 18,461
  • 9
  • 58
  • 95

3 Answers3

7

A VCS isn't the ideal place to store any delivery element (like binaries), mostly because:

  • they won't benefit from the features of a VCS (branch, merge, diff, ...)
  • a DVCS (distributed VCS) would see the size of its repo increase massively at each release, which would then make any clone of said repo quite cumbersome.

Deliveries are better stored in an artefact repository (like for instance Nexus), where checksum keys (SHA1, MD5) will be automatically computed and associated with those deliveries, ensuring you can get them back for using them in production while checking their integrity.

So that means having a separate repository (from the VCS one) in order to manage those elements.


As mentioned in Useless's answer, you could use git notes to associate a binary blob to a git object (including a tag)

In principle, a note is a regular Git blob, and any kind of (non-)format is accepted. You can binary-safely create notes from arbitrary files using git hash-object:

$ cc *.c
$ blob=$(git hash-object -w a.out)
$ git notes --ref=built add -C "$blob" HEAD

The only issue is the size of the repo which can grow out of control, if those notes aren't regularly cleaned.


Another approach would be to use git-annex, which allows to associate a git commit with an external content (meaning a content which can be a binary, as large as you need it to be).

git-annex allows managing files with git, without checking the file contents into git.
While that may seem paradoxical, it is useful when dealing with files larger than git can currently easily handle, whether due to limitations in memory, time, or disk space.

Community
  • 1
  • 1
VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
3

The manpage for git notes describes how to use them for associating arbitrary binary blobs with objects. Want a link, or is that enough to be going on with?

Useless
  • 64,155
  • 6
  • 88
  • 132
0

As @VonC says VCS is not ideal to store unversioned binaries.

To solve the problem using only git you could create a separate git repository for artefacts and add source repositories required to recreate them as submodules.

On each public release commit new artefacts to the repository and update the submodules references. Submodules point to commits directly so you always know which sources created particular artifacts.

In general git submodules are very confusing to use, but in this limited case (no branches, no direct editing of submodules) they might be useful.

Beware git is not very suitable to manage big binary files. See Managing large binary files with git.

Community
  • 1
  • 1
jfs
  • 399,953
  • 195
  • 994
  • 1,670