{"thread":{"id":"27149","subject":"[PATCH] submodule update: continue when an update fails","startedAt":"2011-04-21T08:53:21Z","lastAt":"2011-04-21T18:28:00Z","messageCount":2,"participants":["Fredrik Gustafsson","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"166181","messageId":"20110421085321.GA14057@paksenarrion.iveqy.com","threadId":"27149","inReplyTo":null,"subject":"[PATCH] submodule update: continue when an update fails","fromName":"Fredrik Gustafsson","fromEmail":"iveqy@iveqy.com","sentAt":"2011-04-21T08:53:21Z","receivedAt":"2011-04-21T08:53:21Z","isPatch":true,"sender":{"key":"iveqy@iveqy.com","avatar":"https://avatars.githubusercontent.com/u/761743?v=4"},"body":"Hi,\nwhen running git submodule update the scripts stop after failing to\nfetch an submodule. This is errornous because this implies that if a\nsubmodule 'a' isn't availiable then submodule 'x' shouldn't be loaded.\nThis implies a relationship that isn't definied within git.\n\nThere's three different ways to solve this (because the script is runned\nas a childprocess of the git-submodule.sh script):\n\n1. use a global variable (via the export command) to share data between\n processes.\n2. Print outdata from the childprocess to stdout and read it via a pipe\n in the parent process.\n3. Do all error handling in the child process\n\nI've choosen alternative 3 as it seams to have the smallest impact.\n\n\nFrom 7ba07dcfdd99c14522946e923ec63bd0bcd60021 Mon Sep 17 00:00:00 2001\nFrom: Fredrik Gustafsson <iveqy@iveqy.com>\nDate: Mon, 18 Apr 2011 23:08:59 +0200\nSubject: [PATCH] submodule update: continue when an update fails\n\ngit submodule update dies when a remote reference isn't a tree. Instead\nof dying, print an error message and continue update the next submodule\n(and die when all modules are done if there was any errors).\n\nSigned-off-by: Fredrik Gustafsson <iveqy@iveqy.com>\n---\n git-submodule.sh |   30 +++++++++++++++++++++++-------\n 1 files changed, 23 insertions(+), 7 deletions(-)\n\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex b010a67..06ff7f2 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -441,7 +441,8 @@ cmd_update()\n \tfi\n \n \tcloned_modules=\n-\tmodule_list \"$@\" |\n+\terr=\n+\tmodule_list \"$@\" | {\n \twhile read mode sha1 stage path\n \tdo\n \t\tif test \"$stage\" = U\n@@ -521,17 +522,32 @@ cmd_update()\n \t\t\t\t;;\n \t\t\tesac\n \n-\t\t\t(clear_local_git_env; cd \"$path\" && $command \"$sha1\") ||\n-\t\t\tdie \"Unable to $action '$sha1' in submodule path '$path'\"\n-\t\t\tsay \"Submodule path '$path': $msg '$sha1'\"\n+\t\t\tif (clear_local_git_env; cd \"$path\" && $command \"$sha1\")\n+\t\t\tthen\n+\t\t\t\t   say \"Submodule path '$path': $msg '$sha1'\"\n+\t\t\telse\n+\t\t\t\t   say \"Unable to $action '$sha1' in submodule path '$path'\"\n+\t\t\t\t   err=\"Failed to $action one or more submodule(s)\"\n+\t\t\t\t   continue\n+\t\t\tfi\n \t\tfi\n \n \t\tif test -n \"$recursive\"\n \t\tthen\n-\t\t\t(clear_local_git_env; cd \"$path\" && eval cmd_update \"$orig_flags\") ||\n-\t\t\tdie \"Failed to recurse into submodule path '$path'\"\n+\t\t\tif !(clear_local_git_env; cd \"$path\" && eval cmd_update \"$orig_flags\")\n+\t\t\tthen\n+\t\t\t\tsay \"Failed to recurse into submodule path '$path'\"\n+\t\t\t\tcontinue\n+\t\t\tfi\n \t\tfi\n+\n+\tif test -n \"$err\"\n+\tthen\n+\t\tdie $err\n+\tfi\n+\n+\t}\n }\n \n set_name_rev () {\n-- \n1.7.5.rc0.133.gcc4dd.dirty\n\n-- \nMed vänliga hälsningar\nFredrik Gustafsson\n\ntel: 0733-608274\ne-post: iveqy@iveqy.com\n"},{"id":"166197","messageId":"7vpqofxxvz.fsf@alter.siamese.dyndns.org","threadId":"27149","inReplyTo":"20110421085321.GA14057@paksenarrion.iveqy.com","subject":"Re: [PATCH] submodule update: continue when an update fails","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2011-04-21T18:28:00Z","receivedAt":"2011-04-21T18:28:00Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Fredrik Gustafsson <iveqy@iveqy.com> writes:\n\n> when running git submodule update the scripts stop after failing to\n> fetch an submodule. This is errornous because this implies that if a\n> submodule 'a' isn't availiable then submodule 'x' shouldn't be loaded.\n> This implies a relationship that isn't definied within git.\n\nI do not quite understand this. The relationship between 'a' and 'x' are\nclearly defined within your superproject in that they are both submodules\nof it.\n\nIt is indeed asymmetric in that if we fail 'a' we do not even attempt 'x',\nwhile if we succeed a' and then fail 'x', we do not roll-back 'a', i.e. we\ndo not try to be atomic.\n\nOne could argue that if we do not bother to be atomic, it would be better\nto try doing the remainder than stopping at the first failure.  Is that\nwhat you wanted to say?\n\nI suspect that it depends on the nature of the \"failure\" and the state the\nfailure leaves the particular submodule in.  For example, if the failure\nleaves the failed submodule intact (i.e. idempotent and/or no-op), and if\nit fails quickly enough, then it makes perfect sense to keep going and\nfinish all that can succeed.  On the other hand, if it leaves a huge mess\nthe user needs to go in and manually fix (think: conflict resolution),\nsome users may prefer to do so one at a time, instead of having to deal\nwith many independent huge messes that will be left by this change.\n\n> There's three different ways to solve this (because the script is runned\n> as a childprocess of the git-submodule.sh script):\n>\n> 1. use a global variable (via the export command) to share data between\n>  processes.\n\nIt is unclear what you mean by \"share data\"?  Data on what?\n\n> 2. Print outdata from the childprocess to stdout and read it via a pipe\n>  in the parent process.\n\nThe same.  The reason why you need the communication is not explained\nwell. What are you trying to pass from the child to the parent? Why does\nthe parent need to know it?\n\n> 3. Do all error handling in the child process\n\nAhh, so the \"share data\" was about \"the outcome of the processing for one\nsubmodule, if it succeeded, or if it failed and if so how\".\n\n> I've choosen alternative 3 as it seams to have the smallest impact.\n\nAll of the above, if expressed clearly (in other words, when rewritten so\nthat I do not have to say \"I don't understand this\"), should be in the\ncommit log message.\n\n> From 7ba07dcfdd99c14522946e923ec63bd0bcd60021 Mon Sep 17 00:00:00 2001\n> From: Fredrik Gustafsson <iveqy@iveqy.com>\n> Date: Mon, 18 Apr 2011 23:08:59 +0200\n> Subject: [PATCH] submodule update: continue when an update fails\n>\n> git submodule update dies when a remote reference isn't a tree. Instead\n\n\"When a remote reference isn't a tree\"?  I am not sure what you mean.\nWhat remote reference?\n\n> of dying, print an error message and continue update the next submodule\n> (and die when all modules are done if there was any errors).\n\nMore importantly, for the purpose of your change, it does not matter how a\ncommand run for one submodule fails.  Perhaps restate the above like this?\n\n    \"git submodule update\" stops at the first submodule it cannot update.\n    Instead, report the error, continue to update other submodules, and\n    exit with failure status at the end.\n\n> Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>\n> ---\n>  git-submodule.sh |   30 +++++++++++++++++++++++-------\n>  1 files changed, 23 insertions(+), 7 deletions(-)\n>\n> diff --git a/git-submodule.sh b/git-submodule.sh\n> index b010a67..06ff7f2 100755\n> --- a/git-submodule.sh\n> +++ b/git-submodule.sh\n> @@ -441,7 +441,8 @@ cmd_update()\n>  \tfi\n>  \n>  \tcloned_modules=\n> -\tmodule_list \"$@\" |\n> +\terr=\n> +\tmodule_list \"$@\" | {\n>  \twhile read mode sha1 stage path\n>  \tdo\n\nShouldn't this be\n\n\tmodule_list \"$@\" | {\n        err=\n        while read ...\n\tdo\n\nas the $err is only relevant to the child process that is on the\ndownstream of this pipe?\n"}]}