summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Documentation/git-submodule.txt4
-rwxr-xr-xgit-submodule.sh6
-rwxr-xr-xt/t7406-submodule-update.sh29
3 files changed, 38 insertions, 1 deletions
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index e5767134b1..2f18f7daf8 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -159,7 +159,9 @@ update::
This will make the submodules HEAD be detached unless `--rebase` or
`--merge` is specified or the key `submodule.$name.update` is set to
`rebase`, `merge` or `none`. `none` can be overridden by specifying
- `--checkout`.
+ `--checkout`. Setting the key `submodule.$name.update` to `!command`
+ will cause `command` to be run. `command` can be any arbitrary shell
+ command that takes a single argument, namely the sha1 to update to.
+
If the submodule is not yet initialized, and you just want to use the
setting as stored in .gitmodules, you can automatically initialize the
diff --git a/git-submodule.sh b/git-submodule.sh
index 945e296d30..c87515de10 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -860,6 +860,12 @@ Maybe you want to use 'update --init'?")"
say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")"
must_die_on_failure=yes
;;
+ !*)
+ command="${update_module#!}"
+ die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed 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 '\$displaypath'")"
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index cdb0538392..bc7cfcd835 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -294,6 +294,35 @@ test_expect_success 'submodule update - checkout in .git/config' '
)
'
+test_expect_success 'submodule update - command in .git/config' '
+ (cd super &&
+ git config submodule.submodule.update "!git checkout"
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD^
+ ) &&
+ (cd super &&
+ (cd submodule &&
+ compare_head
+ ) &&
+ git submodule update submodule &&
+ cd submodule &&
+ ! compare_head
+ )
+'
+
+test_expect_success 'submodule update - command in .git/config catches failure' '
+ (cd super &&
+ git config submodule.submodule.update "!false"
+ ) &&
+ (cd super/submodule &&
+ git reset --hard HEAD^
+ ) &&
+ (cd super &&
+ test_must_fail git submodule update submodule
+ )
+'
+
test_expect_success 'submodule init picks up rebase' '
(cd super &&
git config -f .gitmodules submodule.rebasing.update rebase &&