{"thread":{"id":"23817","subject":"[PATCH RFC] git-submodule foreach: Add $toplevel variable","startedAt":"2010-05-15T23:20:17Z","lastAt":"2010-05-21T16:10:10Z","messageCount":2,"participants":["Ævar Arnfjörð Bjarmason"],"isPatch":true,"patchVersion":1,"patchTotal":null},"messages":[{"id":"141749","messageId":"1273965617-26731-1-git-send-email-avarab@gmail.com","threadId":"23817","inReplyTo":null,"subject":"[PATCH RFC] git-submodule foreach: Add $toplevel variable","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-15T23:20:17Z","receivedAt":"2010-05-15T23:20:17Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a $toplevel variable accessible to `git submodule foreach`, it\ncontains the absolute path of the top level directory (where\n.gitmodules is).\n\nThis makes it possible to e.g. read data in .gitmodules from within\nforeach commands. I'm using this to configure the branch names I want\nto track for each submodule:\n\n    git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'\n\nFor a little history: This patch is borne out of my continuing fight\nof trying to have Git track the branches of submodules, not just their\ncommits.\n\nObviously that's not how they work (they only track commits), but I'm\njust interested in being able to do:\n\n    git submodule foreach 'git pull'\n\nOf course that won't work because the submodule is in a disconnected\nhead, so I first have to connect it, but connect it *to what*.\n\nFor a while I was happy with this because as fate had it, it just so\nhappened to do what I meant:\n\n    git submodule foreach 'git checkout $(git describe --all --always) && git pull'\n\nBut then that broke down, if there's a tag and a branch the tag will\nwin out, and I can't git pull a branch:\n\n    $ git branch -a\n    * master\n      remotes/origin/HEAD -> origin/master\n      remotes/origin/master\n    $ git tag -l\n    release-0.0.6\n    $ git describe --always --all\n    release-0.0.6\n\nSo I figured that I might as well start tracking the branches I want\nin .gitmodules itself:\n\n    [submodule \"yaml-mode\"]\n        path = yaml-mode\n        url = git://github.com/yoshiki/yaml-mode.git\n        branch = master\n\nSo now I can just do (as stated above):\n\n    git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'\n\nMaybe there's a less painful way to do *that* (I'd love to hear about\nit). But regardless of that I think it's a good idea to be able to\nknow what the top-level is from git submodule foreach.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n Documentation/git-submodule.txt |    6 ++++--\n git-submodule.sh                |    2 ++\n t/t7407-submodule-foreach.sh    |   10 +++++++---\n 3 files changed, 13 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 2502531..cdabfd2 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -145,10 +145,12 @@ summary::\n \n foreach::\n \tEvaluates an arbitrary shell command in each checked out submodule.\n-\tThe command has access to the variables $name, $path and $sha1:\n+\tThe command has access to the variables $name, $path, $sha1 and\n+\t$toplevel:\n \t$name is the name of the relevant submodule section in .gitmodules,\n \t$path is the name of the submodule directory relative to the\n-\tsuperproject, and $sha1 is the commit as recorded in the superproject.\n+\tsuperproject, $sha1 is the commit as recorded in the superproject,\n+\tand $toplevel is the absolute path to the top-level of the superproject.\n \tAny submodules defined in the superproject but not checked out are\n \tignored by this command. Unless given --quiet, foreach prints the name\n \tof each submodule before evaluating the command.\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 8175cb2..8c562a7 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -271,6 +271,8 @@ cmd_foreach()\n \t\tshift\n \tdone\n \n+\ttoplevel=$(pwd)\n+\n \tmodule_list |\n \twhile read mode sha1 stage path\n \tdo\ndiff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh\nindex 2a52775..db9365b 100755\n--- a/t/t7407-submodule-foreach.sh\n+++ b/t/t7407-submodule-foreach.sh\n@@ -59,11 +59,13 @@ test_expect_success 'setup a submodule tree' '\n sub1sha1=$(cd super/sub1 && git rev-parse HEAD)\n sub3sha1=$(cd super/sub3 && git rev-parse HEAD)\n \n+pwd=$(pwd)\n+\n cat > expect <<EOF\n Entering 'sub1'\n-foo1-sub1-$sub1sha1\n+$pwd/clone-foo1-sub1-$sub1sha1\n Entering 'sub3'\n-foo3-sub3-$sub3sha1\n+$pwd/clone-foo3-sub3-$sub3sha1\n EOF\n \n test_expect_success 'test basic \"submodule foreach\" usage' '\n@@ -71,7 +73,9 @@ test_expect_success 'test basic \"submodule foreach\" usage' '\n \t(\n \t\tcd clone &&\n \t\tgit submodule update --init -- sub1 sub3 &&\n-\t\tgit submodule foreach \"echo \\$name-\\$path-\\$sha1\" > ../actual\n+\t\tgit submodule foreach \"echo \\$toplevel-\\$name-\\$path-\\$sha1\" > ../actual &&\n+\t\tgit config foo.bar zar &&\n+\t\tgit submodule foreach \"git config --file \\\"\\$toplevel/.git/config\\\" foo.bar\"\n \t) &&\n \ttest_cmp expect actual\n '\n-- \n1.7.1.84.gd92f8\n"},{"id":"142051","messageId":"1274458210-4685-1-git-send-email-avarab@gmail.com","threadId":"23817","inReplyTo":"1273965617-26731-1-git-send-email-avarab@gmail.com","subject":"[PATCH] git-submodule foreach: Add $toplevel variable","fromName":"Ævar Arnfjörð Bjarmason","fromEmail":"avarab@gmail.com","sentAt":"2010-05-21T16:10:10Z","receivedAt":"2010-05-21T16:10:10Z","isPatch":true,"sender":{"key":"avarab@gmail.com","avatar":"https://avatars.githubusercontent.com/u/45301?v=4"},"body":"Add a $toplevel variable accessible to `git submodule foreach`, it\ncontains the absolute path of the top level directory (where\n.gitmodules is).\n\nThis makes it possible to e.g. read data in .gitmodules from within\nforeach commands. I'm using this to configure the branch names I want\nto track for each submodule:\n\n    git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'\n\nFor a little history: This patch is borne out of my continuing fight\nof trying to have Git track the branches of submodules, not just their\ncommits.\n\nObviously that's not how they work (they only track commits), but I'm\njust interested in being able to do:\n\n    git submodule foreach 'git pull'\n\nOf course that won't work because the submodule is in a disconnected\nhead, so I first have to connect it, but connect it *to what*.\n\nFor a while I was happy with this because as fate had it, it just so\nhappened to do what I meant:\n\n    git submodule foreach 'git checkout $(git describe --all --always) && git pull'\n\nBut then that broke down, if there's a tag and a branch the tag will\nwin out, and I can't git pull a branch:\n\n    $ git branch -a\n    * master\n      remotes/origin/HEAD -> origin/master\n      remotes/origin/master\n    $ git tag -l\n    release-0.0.6\n    $ git describe --always --all\n    release-0.0.6\n\nSo I figured that I might as well start tracking the branches I want\nin .gitmodules itself:\n\n    [submodule \"yaml-mode\"]\n        path = yaml-mode\n        url = git://github.com/yoshiki/yaml-mode.git\n        branch = master\n\nSo now I can just do (as stated above):\n\n    git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull'\n\nMaybe there's a less painful way to do *that* (I'd love to hear about\nit). But regardless of that I think it's a good idea to be able to\nknow what the top-level is from git submodule foreach.\n\nSigned-off-by: Ævar Arnfjörð Bjarmason <avarab@gmail.com>\n---\n\nSubmitting as a non-RFC as nobody has commented on the RFC for a\nweek. It works for me.\n\n Documentation/git-submodule.txt |    6 ++++--\n git-submodule.sh                |    2 ++\n t/t7407-submodule-foreach.sh    |   10 +++++++---\n 3 files changed, 13 insertions(+), 5 deletions(-)\n\ndiff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt\nindex 2502531..cdabfd2 100644\n--- a/Documentation/git-submodule.txt\n+++ b/Documentation/git-submodule.txt\n@@ -145,10 +145,12 @@ summary::\n \n foreach::\n \tEvaluates an arbitrary shell command in each checked out submodule.\n-\tThe command has access to the variables $name, $path and $sha1:\n+\tThe command has access to the variables $name, $path, $sha1 and\n+\t$toplevel:\n \t$name is the name of the relevant submodule section in .gitmodules,\n \t$path is the name of the submodule directory relative to the\n-\tsuperproject, and $sha1 is the commit as recorded in the superproject.\n+\tsuperproject, $sha1 is the commit as recorded in the superproject,\n+\tand $toplevel is the absolute path to the top-level of the superproject.\n \tAny submodules defined in the superproject but not checked out are\n \tignored by this command. Unless given --quiet, foreach prints the name\n \tof each submodule before evaluating the command.\ndiff --git a/git-submodule.sh b/git-submodule.sh\nindex 8175cb2..8c562a7 100755\n--- a/git-submodule.sh\n+++ b/git-submodule.sh\n@@ -271,6 +271,8 @@ cmd_foreach()\n \t\tshift\n \tdone\n \n+\ttoplevel=$(pwd)\n+\n \tmodule_list |\n \twhile read mode sha1 stage path\n \tdo\ndiff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh\nindex 2a52775..db9365b 100755\n--- a/t/t7407-submodule-foreach.sh\n+++ b/t/t7407-submodule-foreach.sh\n@@ -59,11 +59,13 @@ test_expect_success 'setup a submodule tree' '\n sub1sha1=$(cd super/sub1 && git rev-parse HEAD)\n sub3sha1=$(cd super/sub3 && git rev-parse HEAD)\n \n+pwd=$(pwd)\n+\n cat > expect <<EOF\n Entering 'sub1'\n-foo1-sub1-$sub1sha1\n+$pwd/clone-foo1-sub1-$sub1sha1\n Entering 'sub3'\n-foo3-sub3-$sub3sha1\n+$pwd/clone-foo3-sub3-$sub3sha1\n EOF\n \n test_expect_success 'test basic \"submodule foreach\" usage' '\n@@ -71,7 +73,9 @@ test_expect_success 'test basic \"submodule foreach\" usage' '\n \t(\n \t\tcd clone &&\n \t\tgit submodule update --init -- sub1 sub3 &&\n-\t\tgit submodule foreach \"echo \\$name-\\$path-\\$sha1\" > ../actual\n+\t\tgit submodule foreach \"echo \\$toplevel-\\$name-\\$path-\\$sha1\" > ../actual &&\n+\t\tgit config foo.bar zar &&\n+\t\tgit submodule foreach \"git config --file \\\"\\$toplevel/.git/config\\\" foo.bar\"\n \t) &&\n \ttest_cmp expect actual\n '\n-- \n1.7.1.98.g4a5f\n"}]}