Wednesday, May 08, 2013

Git Tip of the Week: Git Submodules

...
...

Submodules

If you're storing these as separate git repositories, how do you ensure that they are kept in sync with each other? Well, you could use tags and rely on convention to ensure that you can acquire the same version of the assets. However, tags can change (although they're not supposed to) and conventions can be circumvented.

Another way to do it is to store a pointer to the assets. (This is similar to the .bigjobbies file suggested before.) Since they are referenced by hash, as long as you can acquire the hash then you will be able to restore the asset.

Git submodules works these two concepts together, by treating a submodule as a logically checked out directory in another repository, but referring it to it by a pointer rather than a full checkout. The submodule (sub repository) can evolve at its own pace, with its own checkouts, and the parent can refer to it by a fixed hash.

Working with submodules

To add a submodule to an existing project, run git submodule add to define a local directory corresponding to the remote Git project's contents. For example, if you wanted to add the BigJobbies project earlier as a submodule, you could do:


$ git init parent
Initialized empty Git repository in parent/.git/
$ cd parent
(master) $ git submodule add http://github.com/alblue/BigJobbies/
Cloning into BigJobbies...
done.
(master) $ ls -AF
.git/ .gitmodules BigJobbies/
(master) $ cat .gitmodules 
[submodule "BigJobbies"]
path = BigJobbies
(master) $ git status
# On branch master
#
# Initial commit
#
# Changes to be committed:
#   (use "git rm --cached ..." to unstage)
#
# new file:   .gitmodules
# new file:   BigJobbies


Note that this has set up a .gitmodules file and created a BigJobbies directory, corresponding to the BigJobbies cloned data. However, in the git status, it shows up as a file. What's up with that?

If we add the contents, commit, and then look at the tree, we'll get our answer:


(master) $ git commit -m "Added BigJobbies submodule"
[master (root-commit) f34f140] Added BigJobbies submodule
 2 files changed, 4 insertions(+), 0 deletions(-)
 create mode 100644 .gitmodules
 create mode 160000 BigJobbies
(master) $ git ls-tree HEAD
100644 blob 8041b87daf8e7ed034c669c6c5af9d63367dcd78 .gitmodules
160000 commit e9ed329101157ce9be5dc1c2639096bd82d3fa05 BigJobbies
(master) $ (cd BigJobbies; git rev-parse HEAD)
e9ed329101157ce9be5dc1c2639096bd82d3fa05

Read more: AlBlue's Blog
QR: Inline image 1