Added a recurse command to git-submodule. Using this recurse command any git command (for example, git-status, git-diff, git-checkout) can be performed from the top level to all its submodules at any depth; if the module has not been initialized and updated (that is git sumodule init and git submodule update) the script will take care of that too. I needed this feature especially for diff, status and pull; as I am working on a multi module maven project with each module having separate repository due to architecture and future extensibility. Following is the diff with git-submdoule version 1.5.3.7. I also attached the diff and the modified file in the attachment. diff --git a/git-submodule b/git-submodule index b91d626..e819152 100755 --- a/git-submodule +++ b/git-submodule @@ -1,10 +1,11 @@ #!/bin/sh # # git-submodules.sh: add, init, update or list git submodules +# or recurse any git command over the submodules recursively. # # Copyright (c) 2007 Lars Hjemli -USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]' +USAGE='[[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]|[recurse [-v] command arguments ...]]' . git-sh-setup require_work_tree @@ -251,6 +252,78 @@ modules_list() done } +# Simply checks whether the submodule is initialized +# or not. If not initialized it does so. +initializeSubModule() { + if [ ! -d "$1"/.git ]; then + if [ $recurse_verbose -eq 1 ]; then + echo Initializing and updating "$1" + fi + git-submodule init "$1"; git-submodule update "$1" + fi +} + +# This actually traverses the module; checks +# whether the module is initialized or not. +# if not initialized, then done so and then the +# intended command is evaluated. Then it +# recursively goes into it modules. +traverseModule() { + current_dir=`pwd` + dir_path="$current_dir:$dir_path" + initializeSubModule "$1" + cd "$1" + if [ $recurse_verbose -eq 1 ]; then + echo Working in mod $1 @ `pwd` with $2 + fi + eval "$2" + if [ -f .gitmodules ]; then + for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do + traverseModule "$mod_path" "$2" + done + fi + old_dir=$(echo $dir_path | cut -d':' -f1-1) + length_old_dir=`expr "$old_dir" : '.*'` + cd $old_dir + index=$(echo "$length_old_dir+2" | bc) + dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'` +} + +# Propagates or recurses over all the submodules at any +# depth with any git command, e.g. git-clone, git-status, +# git-commit etc., with the arguments supplied exactly as +# it would have been supplied to the command otherwise. +# This actually starts the recursive propagation +propagate() { + project_home=`pwd` + echo Project Home: $project_home + if [ -d $project_home/.git/ ]; then + git_command=$1 + shift + command_arguments="" + for arg in "$@"; do + if [ `expr index "$arg" ' '` -gt 0 ]; then + arg="\"$arg\"" + fi + command_arguments="$command_arguments $arg" + done + if [ $recurse_verbose -eq 1 ]; then + echo GIT Command git-$git_command with arguments\($#\) "$command_arguments" + fi + main_command="git-$git_command $command_arguments" + eval $main_command + if [ -f .gitmodules ]; then + for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do + traverseModule $mod_path "$main_command" + done + fi + else + echo $project_home not a git repo thus exiting + exit + fi +} + +recurse_verbose=0 while test $# != 0 do case "$1" in @@ -286,6 +359,17 @@ do -*) usage ;; + recurse) + recurse=1 + case "$2" in + -v) + recurse_verbose=1 + shift + ;; + esac + shift + break + ;; *) break ;; @@ -303,17 +387,21 @@ case "$add,$branch" in ;; esac -case "$add,$init,$update,$status,$cached" in -1,,,,) + +case "$add,$init,$update,$recurse,$status,$cached" in +1,,,,,) module_add "$@" ;; -,1,,,) +,1,,,,) modules_init "$@" ;; -,,1,,) +,,1,,,) modules_update "$@" ;; -,,,*,*) +,,,1,,) + propagate "$@" + ;; +,,,,*,*) modules_list "$@" ;; *) -- Imran M Yousuf
diff --git a/git-submodule b/git-submodule index b91d626..e819152 100755 --- a/git-submodule +++ b/git-submodule @@ -1,10 +1,11 @@ #!/bin/sh # # git-submodules.sh: add, init, update or list git submodules +# or recurse any git command over the submodules recursively. # # Copyright (c) 2007 Lars Hjemli -USAGE='[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]' +USAGE='[[--quiet] [--cached] [add <repo> [-b branch]|status|init|update] [--] [<path>...]|[recurse [-v] command arguments ...]]' . git-sh-setup require_work_tree @@ -251,6 +252,78 @@ modules_list() done } +# Simply checks whether the submodule is initialized +# or not. If not initialized it does so. +initializeSubModule() { + if [ ! -d "$1"/.git ]; then + if [ $recurse_verbose -eq 1 ]; then + echo Initializing and updating "$1" + fi + git-submodule init "$1"; git-submodule update "$1" + fi +} + +# This actually traverses the module; checks +# whether the module is initialized or not. +# if not initialized, then done so and then the +# intended command is evaluated. Then it +# recursively goes into it modules. +traverseModule() { + current_dir=`pwd` + dir_path="$current_dir:$dir_path" + initializeSubModule "$1" + cd "$1" + if [ $recurse_verbose -eq 1 ]; then + echo Working in mod $1 @ `pwd` with $2 + fi + eval "$2" + if [ -f .gitmodules ]; then + for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do + traverseModule "$mod_path" "$2" + done + fi + old_dir=$(echo $dir_path | cut -d':' -f1-1) + length_old_dir=`expr "$old_dir" : '.*'` + cd $old_dir + index=$(echo "$length_old_dir+2" | bc) + dir_path=`echo $dir_path $index | awk '{print substr($1, $2)}'` +} + +# Propagates or recurses over all the submodules at any +# depth with any git command, e.g. git-clone, git-status, +# git-commit etc., with the arguments supplied exactly as +# it would have been supplied to the command otherwise. +# This actually starts the recursive propagation +propagate() { + project_home=`pwd` + echo Project Home: $project_home + if [ -d $project_home/.git/ ]; then + git_command=$1 + shift + command_arguments="" + for arg in "$@"; do + if [ `expr index "$arg" ' '` -gt 0 ]; then + arg="\"$arg\"" + fi + command_arguments="$command_arguments $arg" + done + if [ $recurse_verbose -eq 1 ]; then + echo GIT Command git-$git_command with arguments\($#\) "$command_arguments" + fi + main_command="git-$git_command $command_arguments" + eval $main_command + if [ -f .gitmodules ]; then + for mod_path in `grep "path =" .gitmodules | awk '{print $3}'`; do + traverseModule $mod_path "$main_command" + done + fi + else + echo $project_home not a git repo thus exiting + exit + fi +} + +recurse_verbose=0 while test $# != 0 do case "$1" in @@ -286,6 +359,17 @@ do -*) usage ;; + recurse) + recurse=1 + case "$2" in + -v) + recurse_verbose=1 + shift + ;; + esac + shift + break + ;; *) break ;; @@ -303,17 +387,21 @@ case "$add,$branch" in ;; esac -case "$add,$init,$update,$status,$cached" in -1,,,,) + +case "$add,$init,$update,$recurse,$status,$cached" in +1,,,,,) module_add "$@" ;; -,1,,,) +,1,,,,) modules_init "$@" ;; -,,1,,) +,,1,,,) modules_update "$@" ;; -,,,*,*) +,,,1,,) + propagate "$@" + ;; +,,,,*,*) modules_list "$@" ;; *)
Attachment:
git-submodule
Description: Binary data