At work I’m involved in some projects that will very likely make heavy use of submodules. The reason is that submodules make it very convenient to make use of a set of “common” code without a ton of duplication. We’re currently breaking our “common” code into packages that can be included in a project independent of each other, and they will likely exist as submodules.
The challenge is that submodule support in Git isn’t quite as polished as you’d like it to be. What do you do if you have 20+ submodules, some of which may be on a branch and contain uncommitted changes that need to be dealt with? What if it’s been two weeks since you last looked at it?
One solution would be to write a git-all script like this (which is simpler than a real git-all would be, and may actually be incorrect):
#!/bin/sh
# git-all
for repo in $(find . -name '.git' -type d | xargs dirname); do
pushd $repo >/dev/null
git $*
popd >/dev/null
done
We used this approach, particularly before the advent of git-submodule, and some projects still use it. It’s not a bad approach, but it’s not really what you want.
Here’s another solution that’s a little more integrated into git itself:
#!/bin/sh
# git-submodule-changes
. git-sh-setup
status=0
for sm in `git-submodule status
| sed 's/^[[:space:]]*\(.*\)/\1/'
| cut -d ' ' -f 2`;
do
pushd $sm >/dev/null
substat=$(git-ls-files -d -m -o -s -u -t
| cut -d ' ' -f 1 | sort | uniq)
substat=$(echo $substat | tr -d '[[:space:]]')
if [ "$substat" != "" ]; then
status=1
fi
printf "%7s %s\n" "$substat" $sm
popd >/dev/null
done
exit $status
I think this works better. An added benefit is that you can do line-based scripting with tools like grep, sed, and awk (and tons of other unix utilities) with it, because all the info appears on one line:
{master}$ git submodule-changes
? sub0
sub1
This isn’t terribly illuminating, but the format is just “[HMRCK?] submodule-path” on each line. The optional codes are the single-character status codes from git-ls-files.
An even better solution would be to build this into git-submodule.sh, which I will look into as I get time.
Andrew Connell
Contact