Our team at work is using git submodules to track re-usable code across projects, and it’s been pretty good so far, but we have hit minor snags along the way (such as the absence of a ‘git submodule rm’ command!). Another one is that using submodules adds a step to the sequence of things you have to do to publish changes: pushing submodule commits. It’s an easy thing to forget, but it’s a headache for anyone on the other end of a pull when git-checkout-index fails. This pre-commit hook script will cause the commit to fail if the commit contains new submodule moments and those moments are not present in the corresponding submodule origin.
#!/bin/sh function array_has { for item in $1 do if [ "$item" = "$2" ]; then return 1; fi done return 0; } diffs=`git diff --cached --name-only` IFS=`echo -en "\n\b"` for smstat in `git submodule 2>/dev/null` do if [[ "$smstat" =~ '^\+(.*)' ]]; then smstat=${BASH_REMATCH[1]} fi head=$(echo $smstat | awk '{print $1}') path=$(echo $smstat | awk '{print $2}') moment=$(git ls-files -s $path | awk '{print $2}') array_has $diffs $path if [ $? ]; then pushd >/dev/null $path for rhead in $(git ls-remote -h origin | awk '{print $1}') do if [ "$(git rev-list $moment ^$rhead)" != "" ] then unpub=1; fi done fi if [[ $unpub -gt 0 ]]; then echo -n "ERROR: you are trying to commit " echo -n "unpublished changes to the $path " echo "submodule." exit 1; fi done exit 0;