Keeping git submodules in sync with your branches

This is a quick trick for making working with git submodules more magic.

One day you might find that using git submodules is needed for your project. It’s probably not necessary for everyday hacking, but if you’re glue-ing things together, it can be quite useful. Puppet-Gluster uses this technique to easily include all the dependencies needed for a Puppet-Gluster+Vagrant automatic deployment.

If you’re a good hacker, you develop things in separate feature branches. Example:

cd code/projectdir/
git checkout -b feat/my-cool-feature
# hack hack hack
git add -p
# add stuff
git commit -m 'my cool new feature'
git push
# yay!

The problem arises if you git pull inside of a git submodule to update it to a particular commit. When you switch branches, the git submodule‘s branch doesn’t move along with you! Personally, I think this is a bug, but perhaps it’s not. In any case, here’s the fix:

add:

#!/bin/bash
exec git submodule update

to your:

<projectdir>/.git/hooks/post-checkout

and then run:

chmod u+x <projectdir>/.git/hooks/post-checkout

and you’re good to go! Here’s an example:

james@computer:~/code/puppet/puppet-gluster$ git checkout feat/yamldata
M vagrant/gluster/puppet/modules/puppet
Switched to branch 'feat/yamldata'
Submodule path 'vagrant/gluster/puppet/modules/puppet': checked out 'f139d0b7cfe6d55c0848d0d338e19fe640a961f2'
james@computer:~/code/puppet/puppet-gluster (feat/yamldata)$ git checkout master
M vagrant/gluster/puppet/modules/puppet
Switched to branch 'master'
Your branch is up-to-date with 'glusterforge/master'.
Submodule path 'vagrant/gluster/puppet/modules/puppet': checked out '07ec49d1f67a498b31b4f164678a76c464e129c4'
james@computer:~/code/puppet/puppet-gluster$ cat .git/hooks/post-checkout
#!/bin/bash
exec git submodule update
james@computer:~/code/puppet/puppet-gluster$

Hope that helps you out too! If someone knows of a use-case when you don’t want this functionality, please let me know! Many thanks to #git for helping me solve this issue!

Happy hacking,

James

 

Advertisements

2 thoughts on “Keeping git submodules in sync with your branches

  1. Have you seen librarian-puppet? http://librarian-puppet.com/

    The tag line says it all: “You can all stop using git submodules now”

    The problem with submodules is that you have less control over when to update them. In your example above, you’re updating the submodule with each checkout. This may lead to you checking out an unstable version of that submodule, which will break the code on which you’re working.

    (It’s been awhile since I used submodules, and I never dug deep into them; so maybe you can submodule a specific release, and manually update that as needed…)

    librarian-puppet solves this by allowing you to check out specific releases of upstream projects (or, optionally, the master branch if you’re so inclined). This also allows you to avoid duplicate submodules in your various Puppet modules. librarian-puppet creates top-level modules (in your /modules/ directory) for all of the upstream projects you’re consuming.

    It’s taken us a little while to get comfortable with librarian-puppet, and it does shift some of the work effort around, but on the whole we’re pretty happy with the transition to it from submodules.

    • I’ve looked at puppet-librarian before… Here are a few comments:

      * I use the submodules so that vagrant integration works out-of-the-box with a git clone –recursive, it’s actually not used for installing the module itself on your existing puppet server. For this librarian could technically be used.

      * I don’t think the issue with checking out a wrong version occurs in this scenario.

      * In any case, I’m happy to accept patches for “Puppetfile”‘s if that would help, as long as they reference paths on github and not the puppet forge, which is deprecated as far as I’m concerned.

      HTH,
      Cheers

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s