This allows the user some finer grained control over how the update is
done. The primary motivation for this was interoperability with stgit
however being able to intercept the submodule update process may prove
useful for integrating or extending other tools.

Signed-off-by: Chris Packham <>

At $dayjob we have a number of users that are accustomed to using stgit.
Stgit doesn't play nicely with git rebase which would be the logical
setting for submodule.*.update for our usage. Instead we need to run
'stg rebase --merged' on those submodules that have been initialised
with stgit.

Our current solution is an in-house script which is a poor substitute
for git submodule update. I'd much rather replace our script with git
submodule update but we do have a requirement to keep stgit for the
foreseeable future.  Rather than narrowing in on stgit it seems logical
to allow an arbitrary update command to be executed.
 Documentation/git-submodule.txt |  8 +++++++-                | 22 +++++++++++++++++++++-
 2 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index e576713..a0d8b89 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -16,7 +16,7 @@ SYNOPSIS
 'git submodule' [--quiet] deinit [-f|--force] [--] <path>...
 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch]
              [-f|--force] [--rebase] [--reference <repository>]
-             [--merge] [--recursive] [--] [<path>...]
+             [--merge] [--recursive] [--exec <command>] [--] [<path>...]
 'git submodule' [--quiet] summary [--cached|--files] [(-n|--summary-limit) <n>]
              [commit] [--] [<path>...]
 'git submodule' [--quiet] foreach [--recursive] <command>
@@ -172,6 +172,12 @@ If `--force` is specified, the submodule will be checked 
out (using
 `git checkout --force` if appropriate), even if the commit specified in the
 index of the containing repository already matches the commit checked out in
 the submodule.
+If `--exec` is specified the next argument is an arbitrary shell command that
+can be used to gain finer control over how the update is done or integrate with
+external tools. The command should take one argument namely the sha1 of the
+commit to update to. The config variable `submodule.$name.update` can be set
+to `exec` along with `submodule.$name.update.command`.
        Show commit summary between the given commit (defaults to HEAD) and
diff --git a/ b/
index eb58c8e..44631c8 100755
--- a/
+++ b/
@@ -9,7 +9,7 @@ USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] 
[--reference <re
    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
    or: $dashless [--quiet] init [--] [<path>...]
    or: $dashless [--quiet] deinit [-f|--force] [--] <path>...
-   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] 
[-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] 
+   or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] 
[-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] 
[--exec <command>] [--] [<path>...]
    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] 
[commit] [--] [<path>...]
    or: $dashless [--quiet] foreach [--recursive] <command>
    or: $dashless [--quiet] sync [--recursive] [--] [<path>...]"
@@ -32,6 +32,7 @@ nofetch=
 # The function takes at most 2 arguments. The first argument is the
 # URL that navigates to the submodule origin repo. When relative, this URL
@@ -677,6 +678,12 @@ cmd_update()
+               --exec)
+                       case "$2" in '') usage ;; esac
+                       update="exec"
+                       update_exec_command="$2"
+                       shift
+                       ;;
@@ -718,6 +725,11 @@ cmd_update()
                        update_module=$(git config submodule."$name".update)
+               if test -z "$update_exec_command"
+               then
+                       exec_command=$(git config 
+               fi
                if test "$update_module" = "none"
                        echo "Skipping submodule '$prefix$sm_path'"
@@ -799,6 +811,14 @@ Maybe you want to use 'update --init'?")"
                                say_msg="$(eval_gettext "Submodule path 
'\$prefix\$sm_path': merged in '\$sha1'")"
+                       exec)
+                               test -n "$exec_command" || \
+                                       die "$(eval_gettext "Unable to update 
'\$prefix\$sm_path' exec command not specified")"
+                               command="$exec_command"
+                               die_msg="$(eval_gettext "Unable to exec 
'\$command \$sha1' in submodule path '\$prefix\$sm_path'")"
+                               say_msg="$(eval_gettext "Submodule path 
'\$prefix\$sm_path': '\$command \$sha1'")"
+                               must_die_on_failure=yes
+                               ;;
                                command="git checkout $subforce -q"
                                die_msg="$(eval_gettext "Unable to checkout 
'\$sha1' in submodule path '\$prefix\$sm_path'")"

To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to
More majordomo info at

Reply via email to