[PATCH v3 2/3] git-submodule foreach: export .gitmodules settings as variables
From: W. Trevor King <hidden>
Date: 2016-06-15 22:55:13
Subsystem:
documentation, the rest · Maintainers:
Jonathan Corbet, Linus Torvalds
From: "W. Trevor King" <redacted> This makes it easy to access per-submodule variables. For example, git submodule foreach 'git checkout $(git config --file $toplevel/.gitmodules submodule.$name.branch) && git pull' can now be reduced to git submodule foreach 'git checkout $submodule_branch && git pull' Every submodule.<name>.<opt> setting from .gitmodules is available as a $submodule_<sanitized-opt> variable. These variables are not propagated recursively into nested submodules. Signed-off-by: W. Trevor King <redacted> Based-on-patch-by: Phil Hord [off-list ref] --- Documentation/git-submodule.txt | 3 +++ git-sh-setup.sh | 20 ++++++++++++++++++++ git-submodule.sh | 16 ++++++++++++++++ t/t7407-submodule-foreach.sh | 29 +++++++++++++++++++++++++++++ 4 files changed, 68 insertions(+) mode change 100644 => 100755 git-sh-setup.sh
diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt
index cbec363..9a99826 100644
--- a/Documentation/git-submodule.txt
+++ b/Documentation/git-submodule.txt@@ -175,6 +175,9 @@ foreach:: $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. + In addition, every submodule.<name>.<opt> setting from .gitmodules + is available as the variable $submodule_<sanitized_opt>. These + variables are not propagated recursively into nested submodules. 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-sh-setup.sh b/git-sh-setup.sh
old mode 100644
new mode 100755
index ee0e0bc..179a920
--- a/git-sh-setup.sh
+++ b/git-sh-setup.sh@@ -222,6 +222,26 @@ clear_local_git_env() { unset $(git rev-parse --local-env-vars) } +# Remove any suspect characters from a user-generated variable name. +sanitize_variable_name() { + VAR_NAME="$1" + printf '%s' "$VAR_NAME" | + sed -e 's/^[^a-zA-Z]/_/' -e 's/[^a-zA-Z0-9]/_/g' +} + +# Return a command for setting a new variable. +# Neither the variable name nor the variable value passed to this +# function need to be sanitized. You need to eval the returned +# string, because new variables set by the function itself don't +# effect the calling process. +set_user_variable() { + VAR_NAME="$1" + VAR_VALUE="$2" + VAR_NAME=$(sanitize_variable_name "$VAR_NAME") + VAR_VALUE=$(printf '%s' "$VAR_VALUE" | + sed -e 's/\\/\\\\/g' -e 's/"/\\"/g') + printf '%s=%s;\n' "$VAR_NAME" "\"$VAR_VALUE\"" +} # Platform specific tweaks to work around some commands case $(uname -s) in
diff --git a/git-submodule.sh b/git-submodule.sh
index bc33112..e4d26f9 100755
--- a/git-submodule.sh
+++ b/git-submodule.sh@@ -434,8 +434,24 @@ cmd_foreach() clear_local_git_env # we make $path available to scripts ... path=$sm_path + + # make all submodule variables available to scripts + eval $( + git config -f .gitmodules --get-regexp "^submodule\.${name}\..*" | + sed -e "s|^submodule\.${name}\.||" | + while read VAR_NAME VAR_VALUE ; do + VAR_NAME=$(printf '%s' "$VAR_NAME" | tr A-Z a-z) + set_user_variable "submodule_${VAR_NAME}" "$VAR_VALUE" + done) + UNSET_CMD=$(set | + sed -n -e 's|^\(submodule_[a-z_]*\)=.*$|\1|p' | + while read VAR_NAME ; do + printf 'unset %s;\n' "$VAR_NAME" + done) + cd "$sm_path" && eval "$@" && + eval "$UNSET_CMD" && if test -n "$recursive" then cmd_foreach "--recursive" "$@"
diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh
index 9b69fe2..46ac746 100755
--- a/t/t7407-submodule-foreach.sh
+++ b/t/t7407-submodule-foreach.sh@@ -313,4 +313,33 @@ test_expect_success 'command passed to foreach --recursive retains notion of std test_cmp expected actual ' +cat > expect <<EOF +Entering 'nested1' +nested1 nested1 wonky"value +Entering 'nested1/nested2' +nested2 nested2 another wonky"value +Entering 'nested1/nested2/nested3' +nested3 nested3 +Entering 'nested1/nested2/nested3/submodule' +submodule submodule +Entering 'sub1' +sub1 sub1 +Entering 'sub2' +sub2 sub2 +Entering 'sub3' +sub3 sub3 +EOF + +test_expect_success 'test foreach environment variables' ' + ( + cd clone2 && + git config -f .gitmodules submodule.nested1.wonky-var "wonky\"value" && + git config -f nested1/.gitmodules submodule.nested2.wonky-var "another wonky\"value" && + git submodule foreach --recursive "echo \$path \$submodule_path \$submodule_wonky_var" > ../actual + ) && + test_i18ncmp expect actual +' +# +#"echo \$toplevel-\$name-\$submodule_path-\$submodule_url" + test_done
--
1.8.0.3.gc2eb43a