git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: Ping Yin <pkufranky@gmail.com>
To: git@vger.kernel.org
Cc: gitster@pobox.com, Ping Yin <pkufranky@gmail.com>
Subject: [PATCH/RFC v2] git-submodule: multi-level module definition
Date: Wed,  5 Mar 2008 00:04:21 +0800	[thread overview]
Message-ID: <1204646661-7776-1-git-send-email-pkufranky@gmail.com> (raw)

This patch allows multi-level module definition in .gitmodules as
Linus and Sven Verdoolaege etc. have suggested in mails
"Let .git/config specify the url for submodules"
(http://article.gmane.org/gmane.comp.version-control.git/48939).

Following shows an example of such a .gitmodules.

.gitmodules with with multiple level of indirection
------------------------------------------------------
[submodule "service"]
   submodule = crawler
   submodule = search
[submodule "crawler"]
   submodule = util
   submodule = imcrawter
[submodule "search"]
   submodule = util
   submodule = imsearch
[submodule "util"]
   url = git://xyzzy/util.git
[submodule "imsearch"]
   path = search/imsearch
   url = git://xyzzy/imsearch.git
[submodule "imcrawler"]
   path = crawler/imcrawter
   url = git://xyzzy/imcrawter.git
------------------------------------------------------

To simplify the case, submodule sections with submodule attribute should
have neither path attribute nor url attribute (if have, should be ignored).

An option '-m|--module-name' is introduced to designate submodules
by logical module names instead of module paths. So follwoing
commands pairs (1,2), (3,4) will be equivalent.

--------------------------------------
$ git submodule a b c           (1)
$ git submodule -m all          (2)
$ git submodule init a b        (3)
$ git submodule -m init all1    (4)
--------------------------------------

"-m|--module-name" options is introduced with which modules are designated
 by logical names instead of real paths as following example shows.

Identical commands forms with/without "--module-name"
---------------------------------------------------
$ git submodule XXX util imcrawler              (1)
$ git submodule XXX -n crawler                  (2)
$ git submodule XXX util imcrawler imsearch     (3)
$ git submodule XXX -n service                  (4)
$ git submodule XXX -n crawler search           (5)

* XXX represents status, update or init, but not add
* (1) and (2) are idetical conditionally (explained below)
* (3), (4) and (5) are identical conditionally
---------------------------------------------------

There are still minor difference between these two forms.

In the no "--module-name" form, the path parameter may be not the real submodule
path, and it just acts as the filter for real submodule paths. While In the
 "--module-name" form, name parameter must be the logical name, and the real
paths corresponding to the logical name may be neither a submodule path nor
even existent.

How to handle such a path depends on the subcommand.
 - status: Output 0{40} as the sha1. Doing this can remind the user to
   add the path as submodule or delete the path from .gitmodules.
 - update: Skip that path and issue a "Not a submodule" warning
 - init: Also init for that path

So in the example above, commands (1) and (2) are identical only when util and
imcrawler are already submodules.

With "--module-name" option, now we can add submodules in batch.

The former workflow to add submodules is adding one by one with
"git submodule add url path" which then modifies .gitmodules. However,
sometimes it may be more convenient to work in the reverse way: edit
.gitmodules first and then add submodules in batch.

Now "git submodule add --module-name modulename" can help us to do that.
It will find all submodules corresponding to the logical name and add them
in batch by using the path and url from .gitmodules. Of course, it will skip
those paths which have already been submodules.

Signed-off-by: Ping Yin <pkufranky@gmail.com>
---
 git-submodule.sh |  131 +++++++++++++++++++++++++++++++++++++++++++++++-------
 1 files changed, 114 insertions(+), 17 deletions(-)

diff --git a/git-submodule.sh b/git-submodule.sh
index a6aaf40..13517b2 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -13,6 +13,7 @@ command=
 branch=
 quiet=
 cached=
+use_module_name=
 
 #
 # print stuff on stdout unless -q was specified
@@ -81,6 +82,75 @@ module_name()
 }
 
 #
+# List all submodule info line by line by given names (path\tname\turl)
+# $@ = module names
+#
+module_info_by_name() {
+	(
+	export GIT_CONFIG=.gitmodules
+	# When names is not given, list all module info
+	if test $# = 0
+	then
+		names=$(git config --get-regexp 'submodule.*.url' |
+			sed 's/submodule.\(.*\).url .*$/\1/' 2>/dev/null
+			)
+		for name in $names
+		do
+			if git config submodule.$name.submodule >/dev/null 2>&1
+			then
+				continue
+			fi
+			url=$(git config submodule.$name.url)
+			path=$(git config submodule.$name.path) || path="$name"
+			sha1=$(git ls-files --stage $path | grep -e '^160000' |
+				awk '{print $2}')
+			test -z "$sha1" && sha1=0000000000000000000000000000000000000000
+			echo "$sha1	$path	$name	$url"
+		done
+		exit
+	fi
+
+	for name
+	do
+		local names=$(git config --get-all submodule.$name.submodule)
+		if test -n "$names"
+		then
+			module_info_by_name $names
+		else
+			url=$(git config submodule.$name.url)
+			test -z "$url" && continue
+			path=$(git config submodule.$name.path) || path="$name"
+			sha1=$(git ls-files --stage $path | grep -e '^160000' |
+				awk '{print $2}')
+			test -z "$sha1" && sha1=0000000000000000000000000000000000000000
+			echo "$sha1	$path	$name	$url"
+		fi
+	done
+	) | LC_ALL=C sort -u
+}
+
+module_info() {
+	if test -n "$use_module_name"
+	then
+		module_info_by_name "$@"
+	else
+		git ls-files --stage -- "$@" | grep -e '^160000 ' |
+		while read mode sha1 stage path
+		do
+			name=$(module_name "$path")
+			if test -n "$name"
+			then
+				url=$(git config submodule."$name".url)
+				echo "$sha1	$path	$name	$url"
+			else
+				echo "$sha1	$path		"
+			fi
+		done | LC_ALL=C sort -u
+	fi
+
+}
+
+#
 # Clone a submodule
 #
 # Prior to calling, cmd_update checks that a possibly existing
@@ -146,6 +216,17 @@ cmd_add()
 		shift
 	done
 
+	if test -n "$use_module_name"
+	then
+		module_info "$@" |
+		while read sha1 path name url
+		do
+			use_module_name=
+			cmd_add "$url" "$path"
+		done
+		return
+	fi
+
 	repo=$1
 	path=$2
 
@@ -220,15 +301,16 @@ cmd_init()
 		shift
 	done
 
-	git ls-files --stage -- "$@" | grep -e '^160000 ' |
-	while read mode sha1 stage path
+	module_info "$@" |
+	while read sha1 path name url
 	do
+		test -z "$name" &&
+		say "No submodule mapping found in .gitmodules for path '$path'" &&
+		continue
 		# Skip already registered paths
-		name=$(module_name "$path") || exit
-		url=$(git config submodule."$name".url)
-		test -z "$url" || continue
+		git config submodule."$name".url >/dev/null 2>&1 &&
+		continue
 
-		url=$(GIT_CONFIG=.gitmodules git config submodule."$name".url)
 		test -z "$url" &&
 		die "No url found for submodule path '$path' in .gitmodules"
 
@@ -274,12 +356,18 @@ cmd_update()
 		shift
 	done
 
-	git ls-files --stage -- "$@" | grep -e '^160000 ' |
-	while read mode sha1 stage path
+	module_info "$@" |
+	while read sha1 path name url
 	do
-		name=$(module_name "$path") || exit
-		url=$(git config submodule."$name".url)
-		if test -z "$url"
+		if test $sha1 = 0000000000000000000000000000000000000000
+		then
+			say "Not a submodule: $name @ $path"
+			continue
+		elif test -z "$name"
+		then
+			say "No submodule mapping found in .gitmodules for path '$path'"
+			continue
+		elif test -z "$url"
 		then
 			# Only mention uninitialized submodules when its
 			# path have been specified
@@ -357,15 +445,21 @@ cmd_status()
 		shift
 	done
 
-	git ls-files --stage -- "$@" | grep -e '^160000 ' |
-	while read mode sha1 stage path
+	module_info "$@" |
+	while read sha1 path name url
 	do
-		name=$(module_name "$path") || exit
-		url=$(git config submodule."$name".url)
-		if test -z "url" || ! test -d "$path"/.git
+		if test $sha1 = 0000000000000000000000000000000000000000
+		then
+			say "*$sha1 $path"
+			continue
+		elif test -z "$name"
+		then
+			say "No submodule mapping found in .gitmodules for path '$path'"
+			continue
+		elif test -z "$url" || ! test -d "$path"/.git
 		then
 			say "-$sha1 $path"
-			continue;
+			continue
 		fi
 		set_name_rev "$path" "$sha1"
 		if git diff-files --quiet -- "$path"
@@ -408,6 +502,9 @@ do
 	--cached)
 		cached=1
 		;;
+	-m|--module-name)
+		use_module_name=1
+		;;
 	--)
 		break
 		;;
-- 
1.5.4.3.347.g5314c


             reply	other threads:[~2008-03-04 16:05 UTC|newest]

Thread overview: 15+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2008-03-04 16:04 Ping Yin [this message]
2008-03-04 16:12 ` [PATCH/RFC v2] git-submodule: multi-level module definition Johannes Schindelin
2008-03-05  2:13   ` Ping Yin
     [not found] ` <7bfdc29a0803041917j16112e80uc0b21707bdfd3fe@mail.gmail.com>
     [not found]   ` <46dff0320803042315t2d89eb6fl325b4b2ef8ddbc44@mail.gmail.com>
2008-03-05  7:16     ` Ping Yin
2008-03-05  7:40       ` Imran M Yousuf
2008-03-05  7:53         ` Ping Yin
2008-03-05  8:03           ` Imran M Yousuf
2008-03-05 23:18 ` Junio C Hamano
2008-03-06  1:54   ` Ping Yin
2008-03-06  2:16     ` Imran M Yousuf
2008-03-06  2:32     ` Johannes Schindelin
2008-03-06  5:18       ` Ping Yin
2008-03-06  3:48     ` Junio C Hamano
2008-03-06  5:48       ` Ping Yin
2008-03-07  1:43         ` Ping Yin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: http://vger.kernel.org/majordomo-info.html

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1204646661-7776-1-git-send-email-pkufranky@gmail.com \
    --to=pkufranky@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=gitster@pobox.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this public inbox

	https://80x24.org/mirrors/git.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).