git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[RFC PATCH 2/2] submodule update: continue when a checkout fails

From
Fredrik Gustafsson <iveqy@iveqy.com>
Date
May 15, 2011, 12:42 UTC
Message-ID
<551b190565139229c6f374eeba11dd8486375a1d.1305462132.git.iveqy@iveqy.com>
In-Reply-To
<cover.1305462132.git.iveqy@iveqy.com>

When running git submodule update the submodules are checked out in alphabetic order. When an update of a submodule fails because of a checkout error, continue to the next submodule and when done with all submodules, exit with an error.

We only do this for 'safe' case when a submodule is not marked as rebase or merge. When the update of a submodule fails because of a merge or rebase, the update will still die immediately to give the user an opportunity to resolve any conflicts before continuing.

Since submodule 'b' does not necessarily need to be dependent on submodule 'a' this behavior is helpful if we have a lot of submodules. For example if some submodules currently experience network problems we can securely continue with the other submodules and the user can revisit the failed one later on.

It also is helpful if a checkout fails because a submodules working directory is dirty. Now the user can cleanup the submodule in question and another git submodule update will just update the failed submodule instead of all submodules that are ordered alphabetically afterwards.

Signed-off-by: Fredrik Gustafsson <iveqy@iveqy.com>
Mentored-by: Jens Lehmann <Jens.Lehmann@web.de>
Mentored-by: Heiko Voigt <hvoigt@hvoigt.net>
---
 git-submodule.sh            |   42 ++++++++++++++++++++++++++++++++++++------
 t/t7406-submodule-update.sh |   29 +++++++++++++++++++++++++++++
 2 files changed, 65 insertions(+), 6 deletions(-)
diff --git a/git-submodule.sh b/git-submodule.sh
index bf110e9..02c41c7 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -444,7 +444,8 @@ cmd_update()
 	fi
 
 	cloned_modules=
-	module_list "$@" |
+	module_list "$@" | {
+	err=
 	while read mode sha1 stage path
 	do
 		if test "$stage" = U
@@ -525,17 +526,46 @@ cmd_update()
 				;;
 			esac
 
-			(clear_local_git_env; cd "$path" && $command "$sha1") ||
-			die "Unable to $action '$sha1' in submodule path '$path'"
-			say "Submodule path '$path': $msg '$sha1'"
+			if (clear_local_git_env; cd "$path" && $command "$sha1")
+			then
+				say "Submodule path '$path': $msg '$sha1'"
+			else
+				case $action in
+				rebase|merge)
+					die "Unable to $action '$sha1' in submodule path '$path'" 2
+					;;
+				*)
+					say "Unable to $action '$sha1' in submodule path '$path'"
+					err="Failed to $action one or more submodule(s)"
+					continue
+					;;
+				esac
+			fi
 		fi
 
 		if test -n "$recursive"
 		then
-			(clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags") ||
-			die "Failed to recurse into submodule path '$path'"
+			(clear_local_git_env; cd "$path" && eval cmd_update "$orig_flags")
+			res=$?
+			if test $res -gt 0
+			then
+				if test $res -eq 1
+				then
+					say "Failed to recurse into submodule path '$path'"
+					continue
+				else
+					die "Failed to recurse into submodule path '$path'" $res
+				fi
+			fi
 		fi
 	done
+
+	if test -n "$err"
+	then
+		die "$err"
+	fi
+
+	}
 }
 
 set_name_rev () {
diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh
index 4f16fcc..e79c4df 100755
--- a/t/t7406-submodule-update.sh
+++ b/t/t7406-submodule-update.sh
@@ -298,4 +298,33 @@ test_expect_success 'submodule update ignores update=rebase config for new submo
 	)
 '
 
+test_expect_success 'submodule update continues after checkout error' '
+	(cd super &&
+	 git reset --hard HEAD &&
+	 git submodule add ../submodule submodule2 &&
+	 git submodule init &&
+	 git commit -am "new_submodule" &&
+	 (cd submodule2 &&
+	  git rev-parse HEAD > ../expect
+	 ) &&
+	 (cd submodule &&
+	  test_commit "update_submodule" file
+	 ) &&
+	 (cd submodule2 &&
+	  test_commit "update_submodule2" file
+	 ) &&
+	 git add submodule &&
+	 git add submodule2 &&
+	 git commit -m "two_new_submodule_commits" &&
+	 (cd submodule &&
+	 	echo "" > file
+	 ) &&
+	 git checkout HEAD^ &&
+	 test_must_fail git submodule update &&
+	 (cd submodule2 &&
+	  git rev-parse HEAD > ../actual
+	 ) &&
+	 test_cmp expect actual
+	) 
+'
 test_done
-- 
1.7.5.1.219.ge2152.dirty
Previous: Junio C HamanoNext: Junio C Hamano
Message 4 of 5 in “submodule update continue”
  1. 0/2 submodule update continueFredrik Gustafsson, May 15, 2011
  2. 1/2 sh-setup: Make die take the error code as param.Fredrik Gustafsson, May 15, 2011
  3. Junio C HamanoMay 15, 2011
  4. 2/2 submodule update: continue when a checkout failsFredrik Gustafsson, May 15, 2011
  5. Junio C HamanoMay 15, 2011

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.