Working with git submodules recursively

Git submodules are a relatively decent way to compose multiple source trees together, but they definitely fall short in a number of areas (which others have discussed at length elsewhere). One thing that immediately irritated me was that there is no way to recursively update, commit, push, etc., across all of one’s project’s submodules. This is something I ran into immediately upon moving to git from svn some months back, and it almost scared me away from git (we used a lot of svn:externals, and now a lot of git submodules).

Thankfully, the raw materials are there in git to work around this. (I’ve since noticed a bunch of other attempts to do similar things, but they all seem way more complicated than my approach…maybe it’s the perl? ;-))

Here’s the script we use for operating over git submodules recursively, git-submodule-recur.sh:

#!/bin/sh

case "$1" in
        "init") CMD="submodule update --init" ;;
        *) CMD="$*" ;;
esac

git $CMD
git submodule foreach "$0" $CMD

Throw that into your $PATH (I trim the .sh), chmod +x, and git submodules become pretty pleasant to work with. All this is doing is applying whatever arguments you would otherwise provide to git within each submodule, and their submodules, etc., all the way down. The one special invocation, git-submodule-recur init, just executes git submodule update --init in all submodules.

So, want to get the status of your current working directory, and all submodules? git-submodule-recur status Want to commit all modifications in cwd and all submodules? git-submodule-recur commit -a -m "some comment" Want to push all commits? git-submodule-recur push You get the picture.

This script has saved me a *ton* of typing over the past months. Hopefully, it finds a good home elsewhere, too.

Note: Starting in git 1.6.5, git submodule will grow a –recursive option for the foreach, update and status commands. That’s very helpful for the most common actions (and critical for building projects that have submodules in CI containers like hudson), but git-submodule-recur definitely still has a place IMO, especially for pushing.

Update 2009/09/28: I tweaked the git-submodule-recur script to quote the path to the script ("$0" instead of $0); this became necessary when I dropped the script into C:\Program Files\Git\bin in our Windows-hosted Hudson environment.

About these ads
This entry was posted in geek, Random Software Geekery. Bookmark the permalink.

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