Thread (13 messages) flat view 13 messages, 3 authors, 2016-06-15

Re: [PATCH] Add git-submodule command

From: Johannes Schindelin <hidden>
Date: 2016-06-15 22:43:12

Hi,

On Fri, 25 May 2007, Lars Hjemli wrote:
There is currently no way to override the mappings in the .gitmodules 
file, except by manually creating the subproject repository.
I think that is okay. We can add that easily at a later stage, and the 
script is much easier without that logic.
quoted hunk ↗ jump to hunk
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
Looks good here, I checked with asciidoc.
quoted hunk ↗ jump to hunk
diff --git a/git-submodule.sh b/git-submodule.sh
new file mode 100755
index 0000000..c4a1cc3
--- /dev/null
+++ b/git-submodule.sh
@@ -0,0 +1,163 @@
+#!/bin/sh
+#
+# git-submodule.sh: init, update or list git submodules
+#
+# Copyright (c) 2007 Lars Hjemli
+
+USAGE='[-i | --init | -u | --update] [-q | --quiet] [--cached] <path>...'
+. git-sh-setup
+require_work_tree
+
+init=
+update=
+quiet=
+cached=
+
+#
+# print stuff on stdout unless -q was specified
+#
+say()
+{
+	if test -z "$quiet"
+	then
+		echo -e "$@"
+	fi
+}
+
+#
+# Find all (requested) submodules, run clone + checkout on missing paths
+#
+# $@ = requested paths (default to all)
+#
+modules_init()
+{
+	git ls-files --stage -- $@ | grep -e '^160000 ' |
Any reason you read in the stage? It does not seem that you use it.
+	while read mode sha1 stage path
+	do
+		test -d "$path/.git" && continue
+
+		if test -d "$path"
+		then
+			rmdir "$path" 2>/dev/null ||
+			die "Directory '$path' exist, but not as a submodule"
+		fi
+
+		test -e "$path" &&
+		die "A file already exist at path '$path'"
+
+		url=$(GIT_CONFIG=.gitmodules git-config module."$path".url)
I like that command ;-)
+		test -z "$url" &&
+		die "No url found for submodule '$path' in .gitmodules"
+
+		git-clone "$url" "$path" ||
+		die "Clone of submodule '$path' failed"
+
+		$(cd "$path" && git-checkout -q "$sha1") ||
+		die "Checkout of submodule '$path' failed"
+
+		say "Submodule '$path' initialized"
+	done
+}
+
+#
+# Checkout correct revision of each initialized submodule
+#
+# $@ = requested paths (default to all)
+#
+modules_update()
+{
+	git ls-files --stage -- $@ | grep -e '^160000 ' |
Same here.
+	while read mode sha1 stage path
+	do
+		if ! test -d "$path/.git"
+		then
+			say "Submodule '$path' not initialized"
+			continue;
+		fi
+		subsha1=$(cd "$path" && git-rev-parse --verify HEAD) ||
Maybe it would be a better idea to use "git --git-dir="$path" rev-parse 
..."? Just in case somebody calls this with GIT_DIR overridden...

Or, unset GIT_DIR explicitely.
+		die "Unable to find current revision of submodule '$path'"
+
+		if test "$subsha1" != "$sha1"
+		then
+			$(cd "$path" && git-fetch && git-checkout -q "$sha1") ||
This will make a detached HEAD, right? Do you want that? (I am not really 
interested in submodules myself, so I haven't thought about it, and I 
haven't followed that monster discussion.)
+			die "Unable to checkout revision $sha1 of submodule '$path'"
+
+			say "Submodule '$path' reset to revision $sha1"
I'd rather not say "reset", since this has a different meaning in Git, but 
rather "set to revision $sha1".
+		fi
+	done
+}
+
+#
+# List all registered submodules, prefixed with:
+#  - submodule not initialized
+#  + different version checked out
+#
+# If --cached was specified the revision in the index will be printed
+# instead of the currently checked out revision.
+#
+# $@ = requested paths (default to all)
+#
+modules_list()
+{
+	git ls-files --stage -- $@ | grep -e '^160000 ' |
+	while read mode sha1 stage path
+	do
+		if ! test -d "$path/.git"
+		then
+			say "-$sha1 $path"
+			continue;
+		fi
+		revname=$(cd "$path" && git-describe $sha1)
+		if git diff-files --quiet -- "$path"
+		then
+			say " $sha1 $path\t($revname)"
+		else
+			if test -z "$cached"
+			then
+				sha1=$(cd "$path" && git-rev-parse --verify HEAD)
+				revname=$(cd "$path" && git-describe $sha1)
+			fi
+			say "+$sha1 $path\t($revname)"
+		fi
+	done
+}
+
+
+while case "$#" in 0) break ;; esac
+do
+	case "$1" in
+	-i|--init)
+		init=1
+		;;
+	-u|--update)
+		update=1
+		;;
+	-q|--quiet)
+		quiet=1
+		;;
+	--cached)
+		cached=1
+		;;
+	--)
+		break
+		;;
+	-*)
+		usage
+		;;
+	*)
+		break
+		;;
+	esac
+	shift
+done
+
+
+if test "$init" = "1"
+then
+	modules_init $@
+elif test "$update" = "1"
+then
+	modules_update $@
+else
+	modules_list $@
+fi
I'll let Junio comment on that command line parsing...

All in all, I like it: it is short, to the point, and it should do the job 
(maybe with a few enhancements like "--update" without arguments means 
_all_ submodules).

Ciao,
Dscho
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help