{"thread":{"id":"54227","subject":"Cannot run `git submodule init` on Cygwin from script with strict error checking","startedAt":"2020-09-11T08:20:55Z","lastAt":"2020-09-15T20:31:45Z","messageCount":6,"participants":["Jędrzej Dudkiewicz","Adam Dinwoodie","SZEDER Gábor","Junio C Hamano"],"isPatch":false,"patchVersion":null,"patchTotal":null},"messages":[{"id":"405398","messageId":"CABJqhQNh2Qc2Btp==bGUbT-AaSjGdGEmhtphQQyX=nqjWOis0A@mail.gmail.com","threadId":"54227","inReplyTo":null,"subject":"Cannot run `git submodule init` on Cygwin from script with strict error checking","fromName":"Jędrzej Dudkiewicz","fromEmail":"jedrzej.dudkiewicz@gmail.com","sentAt":"2020-09-11T08:20:39Z","receivedAt":"2020-09-11T08:20:55Z","isPatch":false,"sender":{"key":"jedrzej.dudkiewicz@gmail.com","avatar":null},"body":"I'm running git 2.28.0 on Cygwin. I have a script with:\n\nset -aeu\n\nat the beginning (as all scripts should have). In the script I'm trying to run:\n\ngit submodule init\n\nWhen running via \"bash -x script.sh\", I get:\n\n+ git submodule init\n++ basename /usr/libexec/git-core/git-submodule\n++ sed -e 's/-/ /'\n+ dashless='git submodule'\n+ USAGE='[--quiet] [--cached]\n   or: git submodule [--quiet] add [-b <branch>] [-f|--force] [--name\n<name>] [--reference <repository>] [--] <repository> [<path>]\n   or: git submodule [--quiet] status [--cached] [--recursive] [--] [<path>...]\n   or: git submodule [--quiet] init [--] [<path>...]\n   or: git submodule [--quiet] deinit [-f|--force] (--all| [--] <path>...)\n   or: git submodule [--quiet] update [--init] [--remote]\n[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase]\n[--[no-]recommend-shallow] [--reference <repository>] [--recursive]\n[--[no-]single-branch] [--] [<path>...]\n   or: git submodule [--quiet] set-branch (--default|--branch\n<branch>) [--] <path>\n   or: git submodule [--quiet] set-url [--] <path> <newurl>\n   or: git submodule [--quiet] summary [--cached|--files]\n[--summary-limit <n>] [commit] [--] [<path>...]\n   or: git submodule [--quiet] foreach [--recursive] <command>\n   or: git submodule [--quiet] sync [--recursive] [--] [<path>...]\n   or: git submodule [--quiet] absorbgitdirs [--] [<path>...]'\n+ OPTIONS_SPEC=\n+ SUBDIRECTORY_OK=Yes\n+ . git-sh-setup\n++ unset CDPATH\n++ IFS='\n'\n+++ git --exec-path\n++ . /usr/libexec/git-core/git-sh-i18n\n+++ TEXTDOMAIN=git\n+++ export TEXTDOMAIN\n/usr/libexec/git-core/git-sh-i18n: line 10: GIT_TEXTDOMAINDIR: unbound variable\n\n(TL;DR: This basically boils down to GIT_TEXTDOMAINDIR being unbound,\ni.e. uninitialized/non-existant.)\n\nWhen I exported GIT_TEXTDOMAINDIR with bogus value from my script\nbefore calling \"git submodule init\":\n\nexport GIT_TEXTDOMAINDIR=/bogus/value\n\nI got (only error shown):\n\n/usr/libexec/git-core/git-sh-i18n: line 20: GIT_TEST_GETTEXT_POISON:\nunbound variable\n\nI set it to `false`, restarted and then got:\n\n/usr/libexec/git-core/git-sh-i18n: line 28:\nGIT_INTERNAL_GETTEXT_TEST_FALLBACKS: unbound variable\n\nI set it to empty value, restarted and then got:\n\n/usr/libexec/git-core/git-sh-setup: line 91: LONG_USAGE: unbound variable\n\nThis is when I gave up.\n\nSame script run with git 2.21.0 on Linux has no problems, but I\nhaven't compare differences between two versions, so I don't know why\nit stopped working.\n-- \nJędrzej Dudkiewicz\n\nI really hate this damn machine, I wish that they would sell it.\nIt never does just what I want, but only what I tell it.\n"},{"id":"405399","messageId":"CA+kUOan0N32W22xkoYsGYqM7rJDnc=tjQe_2Hnh2H47=19bbeQ@mail.gmail.com","threadId":"54227","inReplyTo":"CABJqhQNh2Qc2Btp==bGUbT-AaSjGdGEmhtphQQyX=nqjWOis0A@mail.gmail.com","subject":"Re: Cannot run `git submodule init` on Cygwin from script with strict error checking","fromName":"Adam Dinwoodie","fromEmail":"adam@dinwoodie.org","sentAt":"2020-09-11T11:30:21Z","receivedAt":"2020-09-11T11:40:00Z","isPatch":false,"sender":{"key":"adam@dinwoodie.org","avatar":"https://avatars.githubusercontent.com/u/1397507?v=4"},"body":"Hi Jędrzej,\n\nOn Fri, 11 Sep 2020 at 09:20, Jędrzej Dudkiewicz wrote:\n>\n> I'm running git 2.28.0 on Cygwin. I have a script with:\n>\n> set -aeu\n>\n> at the beginning (as all scripts should have). In the script I'm trying to run:\n>\n> git submodule init\n>\n> When running via \"bash -x script.sh\", I get:\n>\n> + git submodule init\n> ++ basename /usr/libexec/git-core/git-submodule\n> ++ sed -e 's/-/ /'\n> + dashless='git submodule'\n> + USAGE='[--quiet] [--cached]\n>    or: git submodule [--quiet] add [-b <branch>] [-f|--force] [--name\n> <name>] [--reference <repository>] [--] <repository> [<path>]\n>    or: git submodule [--quiet] status [--cached] [--recursive] [--] [<path>...]\n>    or: git submodule [--quiet] init [--] [<path>...]\n>    or: git submodule [--quiet] deinit [-f|--force] (--all| [--] <path>...)\n>    or: git submodule [--quiet] update [--init] [--remote]\n> [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase]\n> [--[no-]recommend-shallow] [--reference <repository>] [--recursive]\n> [--[no-]single-branch] [--] [<path>...]\n>    or: git submodule [--quiet] set-branch (--default|--branch\n> <branch>) [--] <path>\n>    or: git submodule [--quiet] set-url [--] <path> <newurl>\n>    or: git submodule [--quiet] summary [--cached|--files]\n> [--summary-limit <n>] [commit] [--] [<path>...]\n>    or: git submodule [--quiet] foreach [--recursive] <command>\n>    or: git submodule [--quiet] sync [--recursive] [--] [<path>...]\n>    or: git submodule [--quiet] absorbgitdirs [--] [<path>...]'\n> + OPTIONS_SPEC=\n> + SUBDIRECTORY_OK=Yes\n> + . git-sh-setup\n> ++ unset CDPATH\n> ++ IFS='\n> '\n> +++ git --exec-path\n> ++ . /usr/libexec/git-core/git-sh-i18n\n> +++ TEXTDOMAIN=git\n> +++ export TEXTDOMAIN\n> /usr/libexec/git-core/git-sh-i18n: line 10: GIT_TEXTDOMAINDIR: unbound variable\n> <snip>\n\nI think there's something odd about the way you're calling `git\nsubmodule init`: it should normally be a separate execution that\nwouldn't inherit the `-aeu` or `-x` settings from the parent Bash\nprocess. It looks like perhaps you're `source`ing or dotting in the\n`git-submodule` script? Whatever it is, I think the issue is down to\nthe way you're using `git submodule`, rather than a problem with Git\nor the Cygwin Git build.\n\nI  did just try to reproduce the problem using Git v2.28.0-1 on\nCygwin, and wasn't able to:\n\n```\n$ cat test.sh\nset -aeu\nrm -rf testdir\nmkdir testdir\ncd testdir\ngit init\ngit submodule init\n\n$ bash -x test.sh\n+ set -aeu\n+ rm -rf testdir\n+ mkdir testdir\n+ cd testdir\n+ git init\nInitialized empty Git repository in /home/adam/testdir/.git/\n+ git submodule init\n\n$ echo $?\n0\n```\n\nHTH\n\nAdam\n"},{"id":"405400","messageId":"CABJqhQMST-n6-uEDpFCUSsYueF_=7ZLPCtj_mQnu679oY99ZVg@mail.gmail.com","threadId":"54227","inReplyTo":"CA+kUOan0N32W22xkoYsGYqM7rJDnc=tjQe_2Hnh2H47=19bbeQ@mail.gmail.com","subject":"Re: Cannot run `git submodule init` on Cygwin from script with strict error checking","fromName":"Jędrzej Dudkiewicz","fromEmail":"jedrzej.dudkiewicz@gmail.com","sentAt":"2020-09-11T11:46:43Z","receivedAt":"2020-09-11T11:47:41Z","isPatch":false,"sender":{"key":"jedrzej.dudkiewicz@gmail.com","avatar":null},"body":"On Fri, Sep 11, 2020 at 1:30 PM Adam Dinwoodie <adam@dinwoodie.org> wrote:\n>\n> Hi Jędrzej,\n\n> I think there's something odd about the way you're calling `git\n> submodule init`: it should normally be a separate execution that\n> wouldn't inherit the `-aeu` or `-x` settings from the parent Bash\n> process.\n\nSorry for not including the test script. Here it is:\n\n----8<----8<----8<-- CUT HERE--8<----8<----8<----8<----\n#!/bin/bash\n\nset -aeu\n\nexport SHELLOPTS\n\nset -x\n\ngit submodule init\n----8<----8<----8<-- CUT HERE--8<----8<----8<----8<----\n\nI use \"export SHELLOPTS\" because I want these flags to be effective in\nsubshells. As a workaround I'm currently calling \"set +u\" before each\nexecution of \"git submodule init\" and my script works, but it isn't\nvery nice and IMHO shouldn't be required (i.e. it would be extremely\nnice if someone fixed it).\n-- \nJędrzej Dudkiewicz\n\nI really hate this damn machine, I wish that they would sell it.\nIt never does just what I want, but only what I tell it.\n"},{"id":"405405","messageId":"20200911131943.GA23146@szeder.dev","threadId":"54227","inReplyTo":"CABJqhQMST-n6-uEDpFCUSsYueF_=7ZLPCtj_mQnu679oY99ZVg@mail.gmail.com","subject":"Re: Cannot run `git submodule init` on Cygwin from script with strict error checking","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2020-09-11T13:19:43Z","receivedAt":"2020-09-11T14:04:50Z","isPatch":false,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Fri, Sep 11, 2020 at 01:46:43PM +0200, Jędrzej Dudkiewicz wrote:\n> On Fri, Sep 11, 2020 at 1:30 PM Adam Dinwoodie <adam@dinwoodie.org> wrote:\n> >\n> > Hi Jędrzej,\n> \n> > I think there's something odd about the way you're calling `git\n> > submodule init`: it should normally be a separate execution that\n> > wouldn't inherit the `-aeu` or `-x` settings from the parent Bash\n> > process.\n> \n> Sorry for not including the test script. Here it is:\n> \n> ----8<----8<----8<-- CUT HERE--8<----8<----8<----8<----\n> #!/bin/bash\n> \n> set -aeu\n> \n> export SHELLOPTS\n> \n> set -x\n> \n> git submodule init\n> ----8<----8<----8<-- CUT HERE--8<----8<----8<----8<----\n> \n> I use \"export SHELLOPTS\" because I want these flags to be effective in\n> subshells.\n\nYou don't need 'export SHELLOPTS' to make those flags effective in\n_subshells_:\n\n  $ cat test.sh \n  #!/bin/sh\n  \n  set -ex\n  \n  (\n          false\n          echo \"after false\"\n  )\n  exit 0\n  $ ./test.sh\n  + false\n  1\n  $ echo $?\n  1\n\nWhat 'export SHELLOPTS' does is make those flags effective even in\nseparate shell scripts executed by your script, but, as you just found\nout, that's not really a good idea, because those scripts are beyond\nyour control.\n\n> As a workaround I'm currently calling \"set +u\" before each\n> execution of \"git submodule init\" and my script works, but it isn't\n> very nice and IMHO shouldn't be required (i.e. it would be extremely\n> nice if someone fixed it).\n\nThe right workaround would be to apply those shell options only to\nyour script, i.e. to remove that 'export SHELLOPTS'.\n\nHaving said that, unlike 'git submodule', 'git-sh-setup' is meant to\nbe dot-sourced into users' shell scripts, and, therefore, should work\nwith the shell options set in users' scripts, including even 'set -u'.\n\nThe patch below may or may not make it work; it's well over two years\nold, and I haven't tested it at all since then.\n\n\n  ---  >8  ---\n\nSubject: [PATCH] git-sh-setup, git-sh-i18n: make our shell libraries work with\n 'set -u'\n\nSigned-off-by: SZEDER Gábor <szeder.dev@gmail.com>\n---\n git-sh-i18n.sh  |  6 +++---\n git-sh-setup.sh | 14 +++++++-------\n 2 files changed, 10 insertions(+), 10 deletions(-)\n\ndiff --git a/git-sh-i18n.sh b/git-sh-i18n.sh\nindex 8eef60b43f..4eb2a7ad70 100644\n--- a/git-sh-i18n.sh\n+++ b/git-sh-i18n.sh\n@@ -7,7 +7,7 @@\n # Export the TEXTDOMAIN* data that we need for Git\n TEXTDOMAIN=git\n export TEXTDOMAIN\n-if test -z \"$GIT_TEXTDOMAINDIR\"\n+if test -z \"${GIT_TEXTDOMAINDIR-}\"\n then\n \tTEXTDOMAINDIR=\"@@LOCALEDIR@@\"\n else\n@@ -17,7 +17,7 @@ export TEXTDOMAINDIR\n \n # First decide what scheme to use...\n GIT_INTERNAL_GETTEXT_SH_SCHEME=fallthrough\n-if test -n \"$GIT_TEST_GETTEXT_POISON\" &&\n+if test -n \"${GIT_TEST_GETTEXT_POISON-}\" &&\n \t    git env--helper --type=bool --default=0 --exit-code \\\n \t\tGIT_TEST_GETTEXT_POISON\n then\n@@ -25,7 +25,7 @@ then\n elif test -n \"@@USE_GETTEXT_SCHEME@@\"\n then\n \tGIT_INTERNAL_GETTEXT_SH_SCHEME=\"@@USE_GETTEXT_SCHEME@@\"\n-elif test -n \"$GIT_INTERNAL_GETTEXT_TEST_FALLBACKS\"\n+elif test -n \"${GIT_INTERNAL_GETTEXT_TEST_FALLBACKS-}\"\n then\n \t: no probing necessary\n elif type gettext.sh >/dev/null 2>&1\ndiff --git a/git-sh-setup.sh b/git-sh-setup.sh\nindex 10d9764185..1cb1c8a2e8 100644\n--- a/git-sh-setup.sh\n+++ b/git-sh-setup.sh\n@@ -66,16 +66,16 @@ say () {\n \tfi\n }\n \n-if test -n \"$OPTIONS_SPEC\"; then\n+if test -n \"${OPTIONS_SPEC-}\"; then\n \tusage() {\n \t\t\"$0\" -h\n \t\texit 1\n \t}\n \n \tparseopt_extra=\n-\t[ -n \"$OPTIONS_KEEPDASHDASH\" ] &&\n+\t[ -n \"${OPTIONS_KEEPDASHDASH-}\" ] &&\n \t\tparseopt_extra=\"--keep-dashdash\"\n-\t[ -n \"$OPTIONS_STUCKLONG\" ] &&\n+\t[ -n \"${OPTIONS_STUCKLONG-}\" ] &&\n \t\tparseopt_extra=\"$parseopt_extra --stuck-long\"\n \n \teval \"$(\n@@ -89,7 +89,7 @@ else\n \t\tdie \"$(eval_gettext \"usage: \\$dashless \\$USAGE\")\"\n \t}\n \n-\tif [ -z \"$LONG_USAGE\" ]\n+\tif [ -z \"${LONG_USAGE-}\" ]\n \tthen\n \t\tLONG_USAGE=\"$(eval_gettext \"usage: \\$dashless \\$USAGE\")\"\n \telse\n@@ -98,7 +98,7 @@ else\n $LONG_USAGE\")\"\n \tfi\n \n-\tcase \"$1\" in\n+\tcase \"${1-}\" in\n \t\t-h)\n \t\techo \"$LONG_USAGE\"\n \t\tcase \"$0\" in *git-legacy-stash) exit 129;; esac\n@@ -366,7 +366,7 @@ esac\n # if we require to be in a git repository.\n git_dir_init () {\n \tGIT_DIR=$(git rev-parse --git-dir) || exit\n-\tif [ -z \"$SUBDIRECTORY_OK\" ]\n+\tif [ -z \"${SUBDIRECTORY_OK-}\" ]\n \tthen\n \t\ttest -z \"$(git rev-parse --show-cdup)\" || {\n \t\t\texit=$?\n@@ -381,7 +381,7 @@ git_dir_init () {\n \t: \"${GIT_OBJECT_DIRECTORY=\"$(git rev-parse --git-path objects)\"}\"\n }\n \n-if test -z \"$NONGIT_OK\"\n+if test -z \"${NONGIT_OK-}\"\n then\n \tgit_dir_init\n fi\n-- \n2.28.0.820.g0db9d372c0\n\n  ---  >8  ---\n\n"},{"id":"405440","messageId":"xmqqsgbonnco.fsf@gitster.c.googlers.com","threadId":"54227","inReplyTo":"20200911131943.GA23146@szeder.dev","subject":"Re: Cannot run `git submodule init` on Cygwin from script with strict error checking","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2020-09-11T19:07:51Z","receivedAt":"2020-09-11T19:08:08Z","isPatch":false,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"SZEDER Gábor <szeder.dev@gmail.com> writes:\n\n> Having said that, unlike 'git submodule', 'git-sh-setup' is meant to\n> be dot-sourced into users' shell scripts, and, therefore, should work\n> with the shell options set in users' scripts, including even 'set -u'.\n\nIs it and should it?\n\ngit-sh-setup was meant to be an implementation detail for our own\nscripts and we know don't use \"-u -e\".  We never cared about\nbackward compatibility for such use by end-users when we made any\nupdate to the git-sh-setup scriptlet.  We freely changed existing\nfeatures and squatted on good names for variables and functions we\nused in it, because it is designed as a private helper library.\n\nHaving said that, we do protect from end-user misconfiguration like\nexporting CDPATH, and protecting ourselves from exporting SHELLOPTS\nis not something I would oppose.\n\nThanks.\n"},{"id":"405564","messageId":"20200915203105.GB23146@szeder.dev","threadId":"54227","inReplyTo":"xmqqsgbonnco.fsf@gitster.c.googlers.com","subject":"Re: Cannot run `git submodule init` on Cygwin from script with strict error checking","fromName":"SZEDER Gábor","fromEmail":"szeder.dev@gmail.com","sentAt":"2020-09-15T20:31:05Z","receivedAt":"2020-09-15T20:31:45Z","isPatch":false,"sender":{"key":"szeder.dev@gmail.com","avatar":"https://avatars.githubusercontent.com/u/116324?v=4"},"body":"On Fri, Sep 11, 2020 at 12:07:51PM -0700, Junio C Hamano wrote:\n> SZEDER Gábor <szeder.dev@gmail.com> writes:\n> \n> > Having said that, unlike 'git submodule', 'git-sh-setup' is meant to\n> > be dot-sourced into users' shell scripts, and, therefore, should work\n> > with the shell options set in users' scripts, including even 'set -u'.\n> \n> Is it and should it?\n> \n> git-sh-setup was meant to be an implementation detail for our own\n> scripts and we know don't use \"-u -e\".  We never cared about\n> backward compatibility for such use by end-users when we made any\n> update to the git-sh-setup scriptlet.  We freely changed existing\n> features and squatted on good names for variables and functions we\n> used in it, because it is designed as a private helper library.\n\nIt has a manpage that it installed by 'make install-doc', and 'man\ngit' advertises it, so I use it in most of my git-foo shell scripts,\ne.g. for 'require_clean_work_tree'.\n\n> Having said that, we do protect from end-user misconfiguration like\n> exporting CDPATH, and protecting ourselves from exporting SHELLOPTS\n> is not something I would oppose.\n> \n> Thanks.\n"}]}