git@vger.kernel.org mailing list mirror (one of many)
 help / color / mirror / code / Atom feed
From: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
To: git@vger.kernel.org
Cc: "Ævar Arnfjörð Bjarmason" <avarab@gmail.com>
Subject: [PATCH RFC] git-submodule foreach: Add $toplevel variable
Date: Sat, 15 May 2010 23:20:17 +0000	[thread overview]
Message-ID: <1273965617-26731-1-git-send-email-avarab@gmail.com> (raw)

Add a $toplevel variable accessible to `git submodule foreach`, it
contains the absolute path of the top level directory (where
.gitmodules is).

This makes it possible to e.g. read data in .gitmodules from within
foreach commands. I'm using this to configure the branch names I want
to track for each submodule:

    git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'

For a little history: This patch is borne out of my continuing fight
of trying to have Git track the branches of submodules, not just their
commits.

Obviously that's not how they work (they only track commits), but I'm
just interested in being able to do:

    git submodule foreach 'git pull'

Of course that won't work because the submodule is in a disconnected
head, so I first have to connect it, but connect it *to what*.

For a while I was happy with this because as fate had it, it just so
happened to do what I meant:

    git submodule foreach 'git checkout $(git describe --all --always) && git pull'

But then that broke down, if there's a tag and a branch the tag will
win out, and I can't git pull a branch:

    $ git branch -a
    * master
      remotes/origin/HEAD -> origin/master
      remotes/origin/master
    $ git tag -l
    release-0.0.6
    $ git describe --always --all
    release-0.0.6

So I figured that I might as well start tracking the branches I want
in .gitmodules itself:

    [submodule "yaml-mode"]
        path = yaml-mode
        url = git://github.com/yoshiki/yaml-mode.git
        branch = master

So now I can just do (as stated above):

    git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'

Maybe there's a less painful way to do *that* (I'd love to hear about
it). But regardless of that I think it's a good idea to be able to
know what the top-level is from git submodule foreach.

Signed-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>
---
 Documentation/git-submodule.txt |    6 ++++--
 git-submodule.sh                |    2 ++
 t/t7407-submodule-foreach.sh    |   10 +++++++---
 3 files changed, 13 insertions(+), 5 deletions(-)

diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index 2502531..cdabfd2 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt
@@ -145,10 +145,12 @@ summary::
 
 foreach::
 	Evaluates an arbitrary shell command in each checked out submodule.
-	The command has access to the variables $name, $path and $sha1:
+	The command has access to the variables $name, $path, $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, and $sha1 is the commit as recorded in the superproject.
+	superproject, $sha1 is the commit as recorded in the superproject,
+	and $toplevel is the absolute path to the top-level of the superproject.
 	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.
diff --git a/git-submodule.sh b/git-submodule.sh
index 8175cb2..8c562a7 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh
@@ -271,6 +271,8 @@ cmd_foreach()
 		shift
 	done
 
+	toplevel=$(pwd)
+
 	module_list |
 	while read mode sha1 stage path
 	do
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 2a52775..db9365b 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh
@@ -59,11 +59,13 @@ test_expect_success 'setup a submodule tree' '
 sub1sha1=$(cd super/sub1 && git rev-parse HEAD)
 sub3sha1=$(cd super/sub3 && git rev-parse HEAD)
 
+pwd=$(pwd)
+
 cat > expect <<EOF
 Entering 'sub1'
-foo1-sub1-$sub1sha1
+$pwd/clone-foo1-sub1-$sub1sha1
 Entering 'sub3'
-foo3-sub3-$sub3sha1
+$pwd/clone-foo3-sub3-$sub3sha1
 EOF
 
 test_expect_success 'test basic "submodule foreach" usage' '
@@ -71,7 +73,9 @@ test_expect_success 'test basic "submodule foreach" usage' '
 	(
 		cd clone &&
 		git submodule update --init -- sub1 sub3 &&
-		git submodule foreach "echo \$name-\$path-\$sha1" > ../actual
+		git submodule foreach "echo \$toplevel-\$name-\$path-\$sha1" > ../actual &&
+		git config foo.bar zar &&
+		git submodule foreach "git config --file \"\$toplevel/.git/config\" foo.bar"
 	) &&
 	test_cmp expect actual
 '
-- 
1.7.1.84.gd92f8

             reply	other threads:[~2010-05-15 23:37 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2010-05-15 23:20 Ævar Arnfjörð Bjarmason [this message]
2010-05-21 16:10 ` [PATCH] git-submodule foreach: Add $toplevel variable Ævar Arnfjörð Bjarmason

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=1273965617-26731-1-git-send-email-avarab@gmail.com \
    --to=avarab@gmail.com \
    --cc=git@vger.kernel.org \
    /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).