submodule: Add --force option for git submodule update

By default git submodule update runs a simple checkout on submodules that
are not up-to-date. If the submodules contains modified or untracked
files, the command may exit sanely with an error:

  $ git submodule update
  error: Your local changes to the following files would be overwritten by
  checkout:
	  file
  Please, commit your changes or stash them before you can switch branches.
  Aborting
  Unable to checkout '1b69c6e55606b48d3284a3a9efe4b58bfb7e8c9e' in
  submodule path 'test1'

In order to reset a whole git submodule tree, a user has to run first 'git
submodule foreach --recursive git checkout -f' and then run 'git submodule
update'.

This patch adds a --force option for the update command (only used for
submodules without --rebase or --merge options). It passes the --force
option to git checkout which will throw away the local changes.

Signed-off-by: Nicolas Morey-Chaisemartin <nmorey@kalray.eu>
Acked-by: Jens Lehmann <Jens.Lehmann@web.de>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Nicolas Morey-Chaisemartin 2011-04-01 11:42:03 +02:00 committed by Junio C Hamano
parent 8e848868ff
commit 9db31bdf5c
3 changed files with 36 additions and 7 deletions

View file

@ -185,8 +185,10 @@ OPTIONS
-f::
--force::
This option is only valid for the add command.
Allow adding an otherwise ignored submodule path.
This option is only valid for add and update commands.
When running add, allow adding an otherwise ignored submodule path.
When running update, throw away local changes in submodules when
switching to a different commit.
--cached::
This option is only valid for status and summary commands. These

View file

@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /')
USAGE="[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]
or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]
or: $dashless [--quiet] init [--] [<path>...]
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]
or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]
or: $dashless [--quiet] foreach [--recursive] <command>
or: $dashless [--quiet] sync [--] [<path>...]"
@ -385,6 +385,9 @@ cmd_update()
-N|--no-fetch)
nofetch=1
;;
-f|--force)
force=$1
;;
-r|--rebase)
update="rebase"
;;
@ -458,10 +461,11 @@ cmd_update()
if test "$subsha1" != "$sha1"
then
force=
if test -z "$subsha1"
subforce=$force
# If we don't already have a -f flag and the submodule has never been checked out
if test -z "$subsha1" -a -z "$force"
then
force="-f"
subforce="-f"
fi
if test -z "$nofetch"
@ -490,7 +494,7 @@ cmd_update()
msg="merged in"
;;
*)
command="git checkout $force -q"
command="git checkout $subforce -q"
action="checkout"
msg="checked out"
;;

View file

@ -74,6 +74,29 @@ test_expect_success 'submodule update detaching the HEAD ' '
)
'
test_expect_success 'submodule update should fail due to local changes' '
(cd super/submodule &&
git reset --hard HEAD~1 &&
echo "local change" > file
) &&
(cd super &&
(cd submodule &&
compare_head
) &&
test_must_fail git submodule update submodule
)
'
test_expect_success 'submodule update should throw away changes with --force ' '
(cd super &&
(cd submodule &&
compare_head
) &&
git submodule update --force submodule &&
cd submodule &&
! compare_head
)
'
test_expect_success 'submodule update --rebase staying on master' '
(cd super/submodule &&
git checkout master