Last active
September 10, 2015 13:19
-
-
Save JohnArchieMckown/9a1413bb419ffcc80912 to your computer and use it in GitHub Desktop.
How to use git to store binary data, such as a "release level" containing executables & other non-textual files
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
On Thu, 10 Sep 2015 00:23:09 -0700 (PDT) | |
[email protected] wrote: | |
> I'm very new to VCS and git, so I have some difficulties to use them. | |
> | |
> I'd like to use git for my embedded projects. I consider a must have | |
> feature the possibility to retrieve the binary files of an old | |
> release. In this way, I can reprogram a real device with EXACTLY the | |
> same binary after some years since the release. | |
> | |
> I understood it's better to not add binary files to the repository. | |
> Indeed I don't need to track binary files for every commit. The only | |
> thing I need is to add additional non-tracked/ignored files | |
> (binaries) to a few commits, usually tags for production releases. | |
> | |
> | |
> How to reach this goal? | |
The simplest solution I can think of, which does not involve any tools | |
outside of Git (well, almost), is using the lesser-known fact Git's | |
object database is able to store arbitrary data -- not necessarily | |
bound to a commit. | |
The basic idea is like this: once the release build is done, you | |
1) Archive the necessary binary files (that's really platform-dependent: | |
on Windows, I'd use plain zip, on POSIX systems, tar + gz or tar + xz | |
or 7zip is supposedly better; in either case it's up to you). | |
This is needed to provide a single file. | |
2) Put it into the object database: | |
$ git hash-object -w path/to/that/archive_file | |
This command will print the SHA-1 name of the file's contents, | |
and by that time, those contents will already be in the Git | |
database in the form of a so-called "blob". | |
3) Tag this object: | |
$ git tag rel-1.2.3-bin that_sha1_name_from_step2 | |
--- | |
(self) combine steps (Linux only?): | |
git tag rel-1.2.3-bin $(git hash-object -w path/to/that/archive_file) | |
--- | |
You might want to add "-a" to this invocation to create an | |
annotated tag instead. | |
4) Push the tag to the "upstream" repo: | |
$ git push origin rel-1.2.3-bin | |
This command will push the tag and the blob it references to the | |
"upstream" repository. | |
At a later point in time you will be able to get the contents of | |
your file back using | |
$ git show rel-1.2.3-bin >path/to/archive_file | |
that is, via simple output redirection. | |
The downside of this approach is that you're going to have two tags per | |
each release: one for "the source" and another one for "the binary". | |
Two other possibilities: | |
* Just add the binary files to make a release commit and then | |
immediately | |
$ git rm --cached all those files | |
afterwards. | |
I dislike this approach precisely because it mixes the sources and the | |
binaries, but pick whatever works for you. If this would be the | |
easiest path, just take it. | |
* Have a separate branch for binaries. | |
After the release, save your binaries somewhere, check out that | |
branch, copy your binaries over, add/remove changes, commit. | |
The downside is that if the size of the tree in your normal | |
("sources") branch is of hefty size, checkout to the "binary" branch | |
and back will take noticeable time. YMMV, of course. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment