Subject: Re: Restart submodule update --recursive

From: Jonathan Nieder <[email-masked]>
Date: Fri, 29 Oct 2010 04:12:02 -0500

Hi Lukasz,

[side note: if you use a newsreader, please reply by mail instead of
through gmane so the Cc: list can be preserved.]

Lukasz Palczewski wrote:

> I think modyfying the git-submodule.sh will be better for me. So I looked into
> it and first problem araised: 
> How do I get a name of submodule with a name of a previous submodule?
[...]
> It would be nice if I could get name like this sub1/nsub1 when I am in submodule
> sub1.

What path do you want to get when there are three levels of submodules?

To understand how git-submodule works, it helps to see how low-level it
is.  The core is this function:

 #
 # Get submodule info for registered submodules
 # $@ = path to limit submodule list
 #
 module_list ()
 {
	git ls-files --error-unmatch --stage -- "$@" | grep '^160000 '
 }

which is just reading submodule entries from the index in the current
repository.  Like all index entries, they are attached to paths relative to
the toplevel of the current repository.

To get a path relative to the toplevel of the superproject using module_list,
you need to build it up as you go along.  For example,

	git submodule foreach --recursive 'echo $prefix'

does this (see cmd_foreach).
---
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 1ed331c..e9bdbca 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -145,17 +145,21 @@ summary::
 
 foreach::
 	Evaluates an arbitrary shell command in each checked out submodule.
-	The command has access to the variables $name, $path, $sha1 and
-	$toplevel:
+	The command has access to the variables $name, $path, $prefix, $sha1,
+	and $toplevel:
 	$name is the name of the relevant submodule section in .gitmodules,
 	$path is the name of the submodule directory relative to the
 	superproject, $sha1 is the commit as recorded in the superproject,
-	and $toplevel is the absolute path to the top-level of the superproject.
+	$toplevel is the absolute path to the top-level of the superproject,
+	and $toplevel/${prefix}$path is the absolute path for any file
+	in the submodule worktree.
 	Any submodules defined in the superproject but not checked out are
 	ignored by this command. Unless given --quiet, foreach prints the name
 	of each submodule before evaluating the command.
 	If --recursive is given, submodules are traversed recursively (i.e.
-	the given shell command is evaluated in nested submodules as well).
+	the given shell command is evaluated in nested submodules as well)
+	and the superproject used to define $toplevel and $prefix is the
+	outermost project.
 	A non-zero return from the command in any submodule causes
 	the processing to terminate. This can be overridden by adding '|| :'
 	to the end of the command.
--