{"thread":{"id":"26958","subject":"[PATCH v2] submodule: Add --force option for git submodule update","startedAt":"2011-04-01T09:42:03Z","lastAt":"2011-04-03T19:21:58Z","messageCount":2,"participants":["Nicolas Morey-Chaisemartin","Jens Lehmann"],"isPatch":true,"patchVersion":2,"patchTotal":null},"messages":[{"id":"164879","messageId":"4D959DEB.3010206@kalray.eu","threadId":"26958","inReplyTo":null,"subject":"[PATCH v2] submodule: Add --force option for git submodule update","fromName":"Nicolas Morey-Chaisemartin","fromEmail":"nmorey@kalray.eu","sentAt":"2011-04-01T09:42:03Z","receivedAt":"2011-04-01T09:42:03Z","isPatch":true,"sender":{"key":"devel-git@morey-chaisemartin.com","avatar":"https://avatars.githubusercontent.com/u/108326?v=4"},"body":"By default git submodule update runs a simple checkout on submodules\nthat are not up-to-date.\nIf the submodules contains modified or untracked files, the command may\nexit sanely with an error:\n\n$ git submodule update\nerror: Your local changes to the following files would be overwritten by\ncheckout:\n\tfile\nPlease, commit your changes or stash them before you can switch branches.\nAborting\nUnable to checkout '1b69c6e55606b48d3284a3a9efe4b58bfb7e8c9e' in\nsubmodule path 'test1'\n\nThis implies that to reset a whole git submodule tree, a user has to run\nfirst 'git submodule foreach --recursive git checkout -f' to then be\nable to run git submodule update.\n\nThis patch adds a --force option for the update command (only used for\nsubmodules without --rebase or --merge options). It passes the --force\noption to git checkout which will throw away the local changes.\n\nSigned-off-by: Nicolas Morey-Chaisemartin <nmorey@kalray.eu>\n---\n\nMuch less intrusive patch that only adds the --force option but do not\nadd unnecessary checkouts to throw away *all* the changes\n\n Documentation/git-submodule.txt |    6 ++++--\n git-submodule.sh                |   14 +++++++++-----\n t/t7406-submodule-update.sh     |   23 +++++++++++++++++++++++\n 3 files changed, 36 insertions(+), 7 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 3a5aa01..328bdad 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -185,8 +185,10 @@ OPTIONS\n \n -f::\n --force::\n-\tThis option is only valid for the add command.\n-\tAllow adding an otherwise ignored submodule path.\n+\tThis option is only valid for add and update commands.\n+\tWhen running add, allow adding an otherwise ignored submodule path.\n+\tWhen running update, throw away local changes in submodules when\n+\tswitching to a different commit.\n \n --cached::\n \tThis option is only valid for status and summary commands.  These\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 3a13397..f732709 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -8,7 +8,7 @@ dashless=$(basename \"$0\" | sed -e 's/-/ /')\n USAGE=\"[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]\n    or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]\n    or: $dashless [--quiet] init [--] [<path>...]\n-   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]\n+   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]\n    or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]\n    or: $dashless [--quiet] foreach [--recursive] <command>\n    or: $dashless [--quiet] sync [--] [<path>...]\"\n@@ -385,6 +385,9 @@ cmd_update()\n \t\t-N|--no-fetch)\n \t\t\tnofetch=1\n \t\t\t;;\n+\t\t-f|--force)\n+\t\t\tforce=$1\n+\t\t\t;;\n \t\t-r|--rebase)\n \t\t\tupdate=\"rebase\"\n \t\t\t;;\n@@ -458,10 +461,11 @@ cmd_update()\n \n \t\tif test \"$subsha1\" != \"$sha1\"\n \t\tthen\n-\t\t\tforce=\n-\t\t\tif test -z \"$subsha1\"\n+\t\t\tsubforce=$force\n+\t\t\t# If we don't already have a -f flag and the submodule has never been checked out\n+\t\t\tif test -z \"$subsha1\" -a -z \"$force\"\n \t\t\tthen\n-\t\t\t\tforce=\"-f\"\n+\t\t\t\tsubforce=\"-f\"\n \t\t\tfi\n \n \t\t\tif test -z \"$nofetch\"\n@@ -490,7 +494,7 @@ cmd_update()\n \t\t\t\tmsg=\"merged in\"\n \t\t\t\t;;\n \t\t\t*)\n-\t\t\t\tcommand=\"git checkout $force -q\"\n+\t\t\t\tcommand=\"git checkout $subforce -q\"\n \t\t\t\taction=\"checkout\"\n \t\t\t\tmsg=\"checked out\"\n \t\t\t\t;;\ndiff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\nindex fa9d23a..5d24d9f 100755\n--- a/t/t7406-submodule-update.sh\n+++ b/t/t7406-submodule-update.sh\n@@ -74,6 +74,29 @@ test_expect_success 'submodule update detaching the HEAD ' '\n \t)\n '\n \n+test_expect_success 'submodule update should fail due to local changes' '\n+\t(cd super/submodule &&\n+\t git reset --hard HEAD~1 &&\n+\t echo \"local change\" > file\n+\t) &&\n+\t(cd super &&\n+\t (cd submodule &&\n+\t  compare_head\n+\t ) &&\n+\t test_must_fail git submodule update submodule\n+\t)\n+'\n+test_expect_success 'submodule update should throw away changes with --force ' '\n+\t(cd super &&\n+\t (cd submodule &&\n+\t  compare_head\n+\t ) &&\n+\t git submodule update --force submodule &&\n+\t cd submodule &&\n+\t ! compare_head\n+\t)\n+'\n+\n test_expect_success 'submodule update --rebase staying on master' '\n \t(cd super/submodule &&\n \t  git checkout master\n-- \n1.7.5.rc0.1.g9f07f.dirty\n"},{"id":"165090","messageId":"4D98C8D6.3050406@web.de","threadId":"26958","inReplyTo":"4D959DEB.3010206@kalray.eu","subject":"Re: [PATCH v2] submodule: Add --force option for git submodule update","fromName":"Jens Lehmann","fromEmail":"jens.lehmann@web.de","sentAt":"2011-04-03T19:21:58Z","receivedAt":"2011-04-03T19:21:58Z","isPatch":true,"sender":{"key":"jens.lehmann@web.de","avatar":"https://avatars.githubusercontent.com/u/135220?v=4"},"body":"Am 01.04.2011 11:42, schrieb Nicolas Morey-Chaisemartin:\n> By default git submodule update runs a simple checkout on submodules\n> that are not up-to-date.\n> If the submodules contains modified or untracked files, the command may\n> exit sanely with an error:\n> \n> $ git submodule update\n> error: Your local changes to the following files would be overwritten by\n> checkout:\n> \tfile\n> Please, commit your changes or stash them before you can switch branches.\n> Aborting\n> Unable to checkout '1b69c6e55606b48d3284a3a9efe4b58bfb7e8c9e' in\n> submodule path 'test1'\n> \n> This implies that to reset a whole git submodule tree, a user has to run\n> first 'git submodule foreach --recursive git checkout -f' to then be\n> able to run git submodule update.\n> \n> This patch adds a --force option for the update command (only used for\n> submodules without --rebase or --merge options). It passes the --force\n> option to git checkout which will throw away the local changes.\n> \n> Signed-off-by: Nicolas Morey-Chaisemartin <nmorey@kalray.eu>\n\nAcked-by: Jens Lehmann <Jens.Lehmann@web.de>\n\n> ---\n> \n> Much less intrusive patch that only adds the --force option but do not\n> add unnecessary checkouts to throw away *all* the changes\n> \n>  Documentation/git-submodule.txt |    6 ++++--\n>  git-submodule.sh                |   14 +++++++++-----\n>  t/t7406-submodule-update.sh     |   23 +++++++++++++++++++++++\n>  3 files changed, 36 insertions(+), 7 deletions(-)\n> \n> diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\n> index 3a5aa01..328bdad 100644\n> --- a/Documentation/git-submodule.txt\n> +++ b/Documentation/git-submodule.txt\n> @@ -185,8 +185,10 @@ OPTIONS\n>  \n>  -f::\n>  --force::\n> -\tThis option is only valid for the add command.\n> -\tAllow adding an otherwise ignored submodule path.\n> +\tThis option is only valid for add and update commands.\n> +\tWhen running add, allow adding an otherwise ignored submodule path.\n> +\tWhen running update, throw away local changes in submodules when\n> +\tswitching to a different commit.\n>  \n>  --cached::\n>  \tThis option is only valid for status and summary commands.  These\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index 3a13397..f732709 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -8,7 +8,7 @@ dashless=$(basename \"$0\" | sed -e 's/-/ /')\n>  USAGE=\"[--quiet] add [-b branch] [-f|--force] [--reference <repository>] [--] <repository> [<path>]\n>     or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...]\n>     or: $dashless [--quiet] init [--] [<path>...]\n> -   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]\n> +   or: $dashless [--quiet] update [--init] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...]\n>     or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...]\n>     or: $dashless [--quiet] foreach [--recursive] <command>\n>     or: $dashless [--quiet] sync [--] [<path>...]\"\n> @@ -385,6 +385,9 @@ cmd_update()\n>  \t\t-N|--no-fetch)\n>  \t\t\tnofetch=1\n>  \t\t\t;;\n> +\t\t-f|--force)\n> +\t\t\tforce=$1\n> +\t\t\t;;\n>  \t\t-r|--rebase)\n>  \t\t\tupdate=\"rebase\"\n>  \t\t\t;;\n> @@ -458,10 +461,11 @@ cmd_update()\n>  \n>  \t\tif test \"$subsha1\" != \"$sha1\"\n>  \t\tthen\n> -\t\t\tforce=\n> -\t\t\tif test -z \"$subsha1\"\n> +\t\t\tsubforce=$force\n> +\t\t\t# If we don't already have a -f flag and the submodule has never been checked out\n> +\t\t\tif test -z \"$subsha1\" -a -z \"$force\"\n>  \t\t\tthen\n> -\t\t\t\tforce=\"-f\"\n> +\t\t\t\tsubforce=\"-f\"\n>  \t\t\tfi\n>  \n>  \t\t\tif test -z \"$nofetch\"\n> @@ -490,7 +494,7 @@ cmd_update()\n>  \t\t\t\tmsg=\"merged in\"\n>  \t\t\t\t;;\n>  \t\t\t*)\n> -\t\t\t\tcommand=\"git checkout $force -q\"\n> +\t\t\t\tcommand=\"git checkout $subforce -q\"\n>  \t\t\t\taction=\"checkout\"\n>  \t\t\t\tmsg=\"checked out\"\n>  \t\t\t\t;;\n> diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh\n> index fa9d23a..5d24d9f 100755\n> --- a/t/t7406-submodule-update.sh\n> +++ b/t/t7406-submodule-update.sh\n> @@ -74,6 +74,29 @@ test_expect_success 'submodule update detaching the HEAD ' '\n>  \t)\n>  '\n>  \n> +test_expect_success 'submodule update should fail due to local changes' '\n> +\t(cd super/submodule &&\n> +\t git reset --hard HEAD~1 &&\n> +\t echo \"local change\" > file\n> +\t) &&\n> +\t(cd super &&\n> +\t (cd submodule &&\n> +\t  compare_head\n> +\t ) &&\n> +\t test_must_fail git submodule update submodule\n> +\t)\n> +'\n> +test_expect_success 'submodule update should throw away changes with --force ' '\n> +\t(cd super &&\n> +\t (cd submodule &&\n> +\t  compare_head\n> +\t ) &&\n> +\t git submodule update --force submodule &&\n> +\t cd submodule &&\n> +\t ! compare_head\n> +\t)\n> +'\n> +\n>  test_expect_success 'submodule update --rebase staying on master' '\n>  \t(cd super/submodule &&\n>  \t  git checkout master\n"}]}