submodule update: allow custom command to update submodule working tree

Users can set submodule.$name.update to '!command' which will cause
'command' to be run instead of checkout/merge/rebase. This allows
the user 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 with or extending other tools.

Signed-off-by: Chris Packham <judge.packham@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Chris Packham 2013-07-03 21:02:02 +12:00 committed by Junio C Hamano
parent d9857bfd4d
commit 6cb5728c43
3 changed files with 38 additions and 1 deletions

View File

@ -159,7 +159,9 @@ update::
This will make the submodules HEAD be detached unless `--rebase` or This will make the submodules HEAD be detached unless `--rebase` or
`--merge` is specified or the key `submodule.$name.update` is set to `--merge` is specified or the key `submodule.$name.update` is set to
`rebase`, `merge` or `none`. `none` can be overridden by specifying `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 If the submodule is not yet initialized, and you just want to use the
setting as stored in .gitmodules, you can automatically initialize the setting as stored in .gitmodules, you can automatically initialize the

View File

@ -860,6 +860,12 @@ Maybe you want to use 'update --init'?")"
say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")" say_msg="$(eval_gettext "Submodule path '\$displaypath': merged in '\$sha1'")"
must_die_on_failure=yes 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" command="git checkout $subforce -q"
die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")" die_msg="$(eval_gettext "Unable to checkout '\$sha1' in submodule path '\$displaypath'")"

View File

@ -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' ' test_expect_success 'submodule init picks up rebase' '
(cd super && (cd super &&
git config -f .gitmodules submodule.rebasing.update rebase && git config -f .gitmodules submodule.rebasing.update rebase &&