{"thread":{"id":"59512","subject":"[PATCH 0/2] test: add support for zsh and zsh completion","startedAt":"2023-04-01T01:59:06Z","lastAt":"2023-04-01T05:33:49Z","messageCount":4,"participants":["Felipe Contreras","Eric Sunshine"],"isPatch":true,"patchVersion":1,"patchTotal":2},"messages":[{"id":"474542","messageId":"20230401015632.103581-1-felipe.contreras@gmail.com","threadId":"59512","inReplyTo":null,"subject":"[PATCH 0/2] test: add support for zsh and zsh completion","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2023-04-01T01:56:30Z","receivedAt":"2023-04-01T01:59:06Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"I have been running these zsh completion tests for many years in my\ngit-completion fork, and they have been sent before to the mailing list [1],\nonly to be ignored.\n\nBut by adding zsh support in the test library it's possible to run them in a\nmore straightforward way (directly in the test script, and not in a separate\nzsh fork for every assert).\n\nBy running these tests it's easy to see the many issues the upstream zsh\ncompletion code has (13 failures), all of which are fixed in git-completion.\n\n[1] https://lore.kernel.org/git/20220830093138.1581538-3-felipe.contreras@gmail.com/\n\nFelipe Contreras (2):\n  test: fix build for zsh\n  test: completion: add zsh tests\n\n t/t9904-completion-zsh.sh | 1143 +++++++++++++++++++++++++++++++++++++\n t/t9904/.gitignore        |    1 +\n t/t9904/.zshrc            |   51 ++\n t/t9904/_git              |    1 +\n t/test-lib.sh             |    5 +\n 5 files changed, 1201 insertions(+)\n create mode 100755 t/t9904-completion-zsh.sh\n create mode 100644 t/t9904/.gitignore\n create mode 100644 t/t9904/.zshrc\n create mode 120000 t/t9904/_git\n\n-- \n2.40.0\n\n"},{"id":"474543","messageId":"20230401015632.103581-2-felipe.contreras@gmail.com","threadId":"59512","inReplyTo":"20230401015632.103581-1-felipe.contreras@gmail.com","subject":"[PATCH 1/2] test: fix build for zsh","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2023-04-01T01:56:31Z","receivedAt":"2023-04-01T01:59:08Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"zsh has the ability to emulate Bourne shell, which is closer to what our\ntesting suite expect.\n\nUsing the POSIX_ARGZERO option makes $0 behave as POSIX seems to define:\nshow the name of the command launched, as opposed to the zsh default:\nthe path of the script.\n\nThis enables many tests, but not all.\n\nWe can run the tests with `zsh --emulate sh` which has more more\ncompatibility, but doing `emulate sh` inside the script allows us to\njust use `zsh`, although it's not as compatible.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/test-lib.sh | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/t/test-lib.sh b/t/test-lib.sh\nindex 62136caee5..d5a9168484 100644\n--- a/t/test-lib.sh\n+++ b/t/test-lib.sh\n@@ -15,6 +15,11 @@\n # You should have received a copy of the GNU General Public License\n # along with this program.  If not, see http://www.gnu.org/licenses/ .\n \n+if test -n \"${ZSH_VERSION-}\"\n+then\n+\temulate sh -o POSIX_ARGZERO\n+fi\n+\n # Test the binaries we have just built.  The tests are kept in\n # t/ subdirectory and are run in 'trash directory' subdirectory.\n if test -z \"$TEST_DIRECTORY\"\n-- \n2.40.0\n\n"},{"id":"474544","messageId":"20230401015632.103581-3-felipe.contreras@gmail.com","threadId":"59512","inReplyTo":"20230401015632.103581-1-felipe.contreras@gmail.com","subject":"[PATCH 2/2] test: completion: add zsh tests","fromName":"Felipe Contreras","fromEmail":"felipe.contreras@gmail.com","sentAt":"2023-04-01T01:56:32Z","receivedAt":"2023-04-01T01:59:15Z","isPatch":true,"sender":{"key":"felipe.contreras@gmail.com","avatar":"https://avatars.githubusercontent.com/u/8358?v=4"},"body":"zsh's completion system is very advanced, but that comes with a\ndisadvantage: there is no easy way to dump the completions. The simplest\nway of doing that is printing them to stdout in a certain format, and\nthen use the zpty module to parse that format and actually print them.\n\nThere is no easier way.\n\nWe also have to simulate `compadd` in order to output the list of\ncompletions in a way that is similar to the bash completion tests.\n\nThe resulting test scripts is very close to the bash completion test\nscript, except some tests don't make sense, and others require minor\nmodifications.\n\nSigned-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n---\n t/t9904-completion-zsh.sh | 1143 +++++++++++++++++++++++++++++++++++++\n t/t9904/.gitignore        |    1 +\n t/t9904/.zshrc            |   51 ++\n t/t9904/_git              |    1 +\n 4 files changed, 1196 insertions(+)\n create mode 100755 t/t9904-completion-zsh.sh\n create mode 100644 t/t9904/.gitignore\n create mode 100644 t/t9904/.zshrc\n create mode 120000 t/t9904/_git\n\ndiff --git a/t/t9904-completion-zsh.sh b/t/t9904-completion-zsh.sh\nnew file mode 100755\nindex 0000000000..65bdaa011e\n--- /dev/null\n+++ b/t/t9904-completion-zsh.sh\n@@ -0,0 +1,1143 @@\n+#!/bin/sh\n+#\n+# Copyright (c) 2012-2023 Felipe Contreras\n+#\n+\n+test_description='test zsh completion'\n+\n+if test -n \"$ZSH_VERSION\"; then\n+\ttrue\n+elif command -v zsh > /dev/null 2>&1; then\n+\texec zsh \"$0\" \"$@\"\n+else\n+\techo '1..0 #SKIP skipping zsh completion tests: zsh not available'\n+\texit 0\n+fi\n+\n+export ZDOTDIR=\"${0:h:a}/t9904\"\n+\n+. ./test-lib.sh\n+\n+emulate zsh\n+\n+zmodload zsh/zpty\n+\n+export SRC_DIR=\"$GIT_BUILD_DIR/contrib/completion/\"\n+\n+run_completion ()\n+{\n+\tlocal log\n+\n+\t# bug in zsh: reset the exit trap\n+\tzpty zsh \"trap - EXIT; zsh -o NO_GLOBAL_RCS\"\n+\tzpty -n -w zsh \"$1\"$'\\t'\n+\tzpty -r zsh log '*<END-CHOICES>'\n+\tzpty -d zsh\n+\n+\tprintf '%s\\n' ${${${(M)${(Qf)log}:#*'<MARK>'*}#*'<MARK>'}%'</MARK>'*} > out\n+\n+\t[[ -s out ]] || { echo > out ; }\n+}\n+\n+# Test high-level completion\n+# Arguments are:\n+# 1: typed text so far (cur)\n+# 2: expected completion\n+test_completion ()\n+{\n+\tif test $# -gt 1\n+\tthen\n+\t\tprintf '%s\\n' \"$2\" >expected\n+\telse\n+\t\tsed -e 's/Z$//' |sort >expected\n+\tfi &&\n+\trun_completion \"$1\" &&\n+\tsort -u out >out_sorted &&\n+\ttest_cmp expected out_sorted\n+}\n+\n+# Test __gitcomp.\n+# The first argument is the typed text so far (cur); the rest are\n+# passed to __gitcomp.  Expected output comes is read from the\n+# standard input, like test_completion().\n+test_gitcomp ()\n+{\n+\tsed -e 's/Z$//' >expected &&\n+\tlocal cur=\"$1\" &&\n+\tshift &&\n+\trun_completion \"git func __gitcomp $(printf \"%q \" \"$@\") $cur\" &&\n+\ttest_cmp expected out\n+}\n+\n+# Test __gitcomp_nl\n+# Arguments are:\n+# 1: current word (cur)\n+# -: the rest are passed to __gitcomp_nl\n+test_gitcomp_nl ()\n+{\n+\tsed -e 's/Z$//' >expected &&\n+\tlocal cur=\"$1\" &&\n+\tshift &&\n+\trun_completion \"git func __gitcomp_nl $(printf \"%q \" \"$@\") $cur\" &&\n+\ttest_cmp expected out\n+}\n+\n+actual=\"$TRASH_DIRECTORY/actual\"\n+\n+if test_have_prereq MINGW\n+then\n+\tROOT=\"$(pwd -W)\"\n+else\n+\tROOT=\"$(pwd)\"\n+fi\n+\n+test_expect_success 'setup for __git_find_repo_path/__gitdir tests' '\n+\tmkdir -p subdir/subsubdir &&\n+\tmkdir -p non-repo &&\n+\tgit init -b main otherrepo\n+'\n+\n+test_expect_success '__gitcomp - trailing space - options' '\n+\ttest_gitcomp \"--re\" \"--dry-run --reuse-message= --reedit-message=\n+\t\t--reset-author\" <<-EOF\n+\t--reuse-message=Z\n+\t--reedit-message=Z\n+\t--reset-author Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - trailing space - config keys' '\n+\ttest_gitcomp \"br\" \"branch. branch.autosetupmerge\n+\t\tbranch.autosetuprebase browser.\" <<-\\EOF\n+\tbranch.Z\n+\tbranch.autosetupmerge Z\n+\tbranch.autosetuprebase Z\n+\tbrowser.Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - option parameter' '\n+\ttest_gitcomp \"--strategy=re\" \"octopus ours recursive resolve subtree\" \\\n+\t\t\"\" \"re\" <<-\\EOF\n+\trecursive Z\n+\tresolve Z\n+\tEOF\n+'\n+\n+test_expect_failure '__gitcomp - prefix' '\n+\ttest_gitcomp \"branch.me\" \"remote merge mergeoptions rebase\" \\\n+\t\t\"branch.maint.\" \"me\" <<-\\EOF\n+\tbranch.maint.merge Z\n+\tbranch.maint.mergeoptions Z\n+\tEOF\n+'\n+\n+test_expect_failure '__gitcomp - suffix' '\n+\ttest_gitcomp \"branch.me\" \"master maint next seen\" \"branch.\" \\\n+\t\t\"ma\" \".\" <<-\\EOF\n+\tbranch.master.Z\n+\tbranch.maint.Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - ignore optional negative options' '\n+\ttest_gitcomp \"--\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+\t--abc Z\n+\t--def Z\n+\t--no-one Z\n+\t--no-... Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - ignore/narrow optional negative options' '\n+\ttest_gitcomp \"--a\" \"--abc --abcdef --no-one -- --no-two\" <<-\\EOF\n+\t--abc Z\n+\t--abcdef Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - ignore/narrow optional negative options' '\n+\ttest_gitcomp \"--n\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+\t--no-one Z\n+\t--no-... Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - expand all negative options' '\n+\ttest_gitcomp \"--no-\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+\t--no-one Z\n+\t--no-two Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp - expand/narrow all negative options' '\n+\ttest_gitcomp \"--no-o\" \"--abc --def --no-one -- --no-two\" <<-\\EOF\n+\t--no-one Z\n+\tEOF\n+'\n+\n+test_expect_failure '__gitcomp - equal skip' '\n+\ttest_gitcomp \"--option=\" \"--option=\" <<-\\EOF &&\n+\n+\tEOF\n+\ttest_gitcomp \"option=\" \"option=\" <<-\\EOF\n+\n+\tEOF\n+'\n+\n+read -r -d \"\" refs <<-\\EOF\n+main\n+maint\n+next\n+seen\n+EOF\n+\n+test_expect_success '__gitcomp_nl - trailing space' '\n+\ttest_gitcomp_nl \"m\" \"$refs\" <<-EOF\n+\tmain Z\n+\tmaint Z\n+\tEOF\n+'\n+\n+test_expect_failure '__gitcomp_nl - prefix' '\n+\ttest_gitcomp_nl \"--fixup=m\" \"$refs\" \"--fixup=\" \"m\" <<-EOF\n+\t--fixup=main Z\n+\t--fixup=maint Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp_nl - suffix' '\n+\ttest_gitcomp_nl \"branch.ma\" \"$refs\" \"branch.\" \"ma\" \".\" <<-\\EOF\n+\tbranch.main.Z\n+\tbranch.maint.Z\n+\tEOF\n+'\n+\n+test_expect_success '__gitcomp_nl - no suffix' '\n+\ttest_gitcomp_nl \"ma\" \"$refs\" \"\" \"ma\" \"\" <<-\\EOF\n+\tmainZ\n+\tmaintZ\n+\tEOF\n+'\n+\n+test_expect_success 'setup for ref completion' '\n+\tgit commit --allow-empty -m initial &&\n+\tgit branch -M main &&\n+\tgit branch matching-branch &&\n+\tgit tag matching-tag &&\n+\t(\n+\t\tcd otherrepo &&\n+\t\tgit commit --allow-empty -m initial &&\n+\t\tgit branch -m main main-in-other &&\n+\t\tgit branch branch-in-other &&\n+\t\tgit tag tag-in-other\n+\t) &&\n+\tgit remote add other \"$ROOT/otherrepo/.git\" &&\n+\tgit fetch --no-tags other &&\n+\trm -f .git/FETCH_HEAD &&\n+\tgit init thirdrepo\n+'\n+\n+test_expect_success 'git switch - with no options, complete local branches and unique remote branch names for DWIM logic' '\n+\ttest_completion \"git switch \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - completes refs and unique remote branches for DWIM' '\n+\ttest_completion \"git checkout \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with --no-guess, complete only local branches' '\n+\ttest_completion \"git switch --no-guess \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete only local branches' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git switch \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - --guess overrides GIT_COMPLETION_CHECKOUT_NO_GUESS=1, complete local branches and unique remote names for DWIM logic' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git switch --guess \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - a later --guess overrides previous --no-guess, complete local and remote unique branches for DWIM' '\n+\ttest_completion \"git switch --no-guess --guess \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - a later --no-guess overrides previous --guess, complete only local branches' '\n+\ttest_completion \"git switch --guess --no-guess \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with GIT_COMPLETION_NO_GUESS=1 only completes refs' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git checkout \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - --guess overrides GIT_COMPLETION_NO_GUESS=1, complete refs and unique remote branches for DWIM' '\n+\tGIT_COMPLETION_CHECKOUT_NO_GUESS=1 test_completion \"git checkout --guess \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --no-guess, only completes refs' '\n+\ttest_completion \"git checkout --no-guess \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - a later --guess overrides previous --no-guess, complete refs and unique remote branches for DWIM' '\n+\ttest_completion \"git checkout --no-guess --guess \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - a later --no-guess overrides previous --guess, complete only refs' '\n+\ttest_completion \"git checkout --guess --no-guess \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with checkout.guess = false, only completes refs' '\n+\ttest_config checkout.guess false &&\n+\ttest_completion \"git checkout \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with checkout.guess = true, completes refs and unique remote branches for DWIM' '\n+\ttest_config checkout.guess true &&\n+\ttest_completion \"git checkout \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - a later --guess overrides previous checkout.guess = false, complete refs and unique remote branches for DWIM' '\n+\ttest_config checkout.guess false &&\n+\ttest_completion \"git checkout --guess \" <<-\\EOF\n+\tHEAD Z\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - a later --no-guess overrides previous checkout.guess = true, complete only refs' '\n+\ttest_config checkout.guess true &&\n+\ttest_completion \"git checkout --no-guess \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with --detach, complete all references' '\n+\ttest_completion \"git switch --detach \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --detach, complete only references' '\n+\ttest_completion \"git checkout --detach \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -d, complete all references' '\n+\ttest_completion \"git switch -d \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -d, complete only references' '\n+\ttest_completion \"git checkout -d \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with --track, complete only remote branches' '\n+\ttest_completion \"git switch --track \" <<-\\EOF\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --track, complete only remote branches' '\n+\ttest_completion \"git checkout --track \" <<-\\EOF\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with --no-track, complete only local branch names' '\n+\ttest_completion \"git switch --no-track \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --no-track, complete only local references' '\n+\ttest_completion \"git checkout --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -c, complete all references' '\n+\ttest_completion \"git switch -c new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -C, complete all references' '\n+\ttest_completion \"git switch -C new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -c and --track, complete all references' '\n+\ttest_completion \"git switch -c new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -C and --track, complete all references' '\n+\ttest_completion \"git switch -C new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -c and --no-track, complete all references' '\n+\ttest_completion \"git switch -c new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with -C and --no-track, complete all references' '\n+\ttest_completion \"git switch -C new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -b, complete all references' '\n+\ttest_completion \"git checkout -b new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -B, complete all references' '\n+\ttest_completion \"git checkout -B new-branch \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -b and --track, complete all references' '\n+\ttest_completion \"git checkout -b new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -B and --track, complete all references' '\n+\ttest_completion \"git checkout -B new-branch --track \" <<-EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -b and --no-track, complete all references' '\n+\ttest_completion \"git checkout -b new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with -B and --no-track, complete all references' '\n+\ttest_completion \"git checkout -B new-branch --no-track \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -c, complete local branches and unique remote branches' '\n+\ttest_completion \"git switch -c \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -C, complete local branches and unique remote branches' '\n+\ttest_completion \"git switch -C \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -c with --no-guess, complete local branches only' '\n+\ttest_completion \"git switch --no-guess -c \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -C with --no-guess, complete local branches only' '\n+\ttest_completion \"git switch --no-guess -C \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -c with --no-track, complete local branches only' '\n+\ttest_completion \"git switch --no-track -c \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - for -C with --no-track, complete local branches only' '\n+\ttest_completion \"git switch --no-track -C \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -b, complete local branches and unique remote branches' '\n+\ttest_completion \"git checkout -b \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -B, complete local branches and unique remote branches' '\n+\ttest_completion \"git checkout -B \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -b with --no-guess, complete local branches only' '\n+\ttest_completion \"git checkout --no-guess -b \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -B with --no-guess, complete local branches only' '\n+\ttest_completion \"git checkout --no-guess -B \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -b with --no-track, complete local branches only' '\n+\ttest_completion \"git checkout --no-track -b \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - for -B with --no-track, complete local branches only' '\n+\ttest_completion \"git checkout --no-track -B \" <<-\\EOF\n+\tmain Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - with --orphan completes local branch names and unique remote branch names' '\n+\ttest_completion \"git switch --orphan \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git switch - --orphan with branch already provided completes nothing else' '\n+\ttest_completion \"git switch --orphan main \" <<-\\EOF\n+\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - with --orphan completes local branch names and unique remote branch names' '\n+\ttest_completion \"git checkout --orphan \" <<-\\EOF\n+\tbranch-in-other Z\n+\tmain Z\n+\tmain-in-other Z\n+\tmatching-branch Z\n+\tEOF\n+'\n+\n+test_expect_success 'git checkout - --orphan with branch already provided completes local refs for a start-point' '\n+\ttest_completion \"git checkout --orphan main \" <<-\\EOF\n+\tHEAD Z\n+\tmain Z\n+\tmatching-branch Z\n+\tmatching-tag Z\n+\tother/branch-in-other Z\n+\tother/main-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'teardown after ref completion' '\n+\tgit branch -d matching-branch &&\n+\tgit tag -d matching-tag &&\n+\tgit remote remove other\n+'\n+\n+test_expect_success 'basic' '\n+\trun_completion \"git \" &&\n+\t# built-in\n+\tgrep -q \"^add\\$\" out &&\n+\t# script\n+\tgrep -q \"^rebase\\$\" out &&\n+\t# plumbing\n+\t! grep -q \"^ls-files\\$\" out &&\n+\n+\trun_completion \"git r\" &&\n+\t! grep -q -v \"^r\" out\n+'\n+\n+test_expect_success 'double dash \"git\" itself' '\n+\ttest_completion \"git --\" <<-\\EOF\n+\t--paginate\n+\t--no-pager\n+\t--git-dir\n+\t--bare\n+\t--version\n+\t--exec-path\n+\t--html-path\n+\t--man-path\n+\t--info-path\n+\t--work-tree\n+\t--namespace\n+\t--no-replace-objects\n+\t--help\n+\tEOF\n+'\n+\n+test_expect_success 'double dash \"git checkout\"' '\n+\ttest_completion \"git checkout --\" <<-\\EOF\n+\t--quiet Z\n+\t--detach Z\n+\t--track Z\n+\t--orphan=Z\n+\t--ours Z\n+\t--theirs Z\n+\t--merge Z\n+\t--conflict=Z\n+\t--patch Z\n+\t--ignore-skip-worktree-bits Z\n+\t--ignore-other-worktrees Z\n+\t--recurse-submodules Z\n+\t--progress Z\n+\t--guess Z\n+\t--no-guess Z\n+\t--no-... Z\n+\t--overlay Z\n+\t--pathspec-file-nul Z\n+\t--pathspec-from-file=Z\n+\tEOF\n+'\n+\n+test_expect_success 'general options' '\n+\ttest_completion \"git --ver\" \"--version\" &&\n+\ttest_completion \"git --hel\" \"--help\" &&\n+\ttest_completion \"git --exe\" \"--exec-path\" &&\n+\ttest_completion \"git --htm\" \"--html-path\" &&\n+\ttest_completion \"git --pag\" \"--paginate\" &&\n+\ttest_completion \"git --no-p\" \"--no-pager\" &&\n+\ttest_completion \"git --git\" \"--git-dir\" &&\n+\ttest_completion \"git --wor\" \"--work-tree\" &&\n+\ttest_completion \"git --nam\" \"--namespace\" &&\n+\ttest_completion \"git --bar\" \"--bare\" &&\n+\ttest_completion \"git --inf\" \"--info-path\" &&\n+\ttest_completion \"git --no-r\" \"--no-replace-objects\"\n+'\n+\n+test_expect_failure 'general options plus command' '\n+\ttest_completion \"git --version check\" \"\" &&\n+\ttest_completion \"git --paginate check\" \"checkout\" &&\n+\ttest_completion \"git --git-dir=foo check\" \"checkout\" &&\n+\ttest_completion \"git --bare check\" \"checkout\" &&\n+\ttest_completion \"git --exec-path=foo check\" \"checkout\" &&\n+\ttest_completion \"git --html-path check\" \"\" &&\n+\ttest_completion \"git --no-pager check\" \"checkout\" &&\n+\ttest_completion \"git --work-tree=foo check\" \"checkout\" &&\n+\ttest_completion \"git --namespace=foo check\" \"checkout\" &&\n+\ttest_completion \"git --paginate check\" \"checkout\" &&\n+\ttest_completion \"git --info-path check\" \"\" &&\n+\ttest_completion \"git --no-replace-objects check\" \"checkout\" &&\n+\ttest_completion \"git --git-dir some/path check\" \"checkout\" &&\n+\ttest_completion \"git -c conf.var=value check\" \"checkout\" &&\n+\ttest_completion \"git -C some/path check\" \"checkout\" &&\n+\ttest_completion \"git --work-tree some/path check\" \"checkout\" &&\n+\ttest_completion \"git --namespace name/space check\" \"checkout\"\n+'\n+\n+test_expect_success 'git --help completion' '\n+\ttest_completion \"git --help ad\" \"add \" &&\n+\ttest_completion \"git --help core\" \"core-tutorial \"\n+'\n+\n+test_expect_success 'setup for integration tests' '\n+\techo content >file1 &&\n+\techo more >file2 &&\n+\tgit add file1 file2 &&\n+\tgit commit -m one &&\n+\tgit branch mybranch &&\n+\tgit tag mytag\n+'\n+\n+test_expect_success 'checkout completes ref names' '\n+\ttest_completion \"git checkout m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git -C <path> checkout uses the right repo' '\n+\ttest_completion \"git -C subdir -C subsubdir -C .. -C ../otherrepo checkout b\" <<-\\EOF\n+\tbranch-in-other Z\n+\tEOF\n+'\n+\n+test_expect_success 'show completes all refs' '\n+\ttest_completion \"git show m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_success '<ref>: completes paths' '\n+\ttest_completion \"git show mytag:f\" <<-\\EOF\n+\tfile1Z\n+\tfile2Z\n+\tEOF\n+'\n+\n+test_expect_success 'complete tree filename with spaces' '\n+\techo content >\"name with spaces\" &&\n+\tgit add \"name with spaces\" &&\n+\tgit commit -m spaces &&\n+\ttest_completion \"git show HEAD:nam\" <<-\\EOF\n+\tname with spacesZ\n+\tEOF\n+'\n+\n+test_expect_success 'complete tree filename with metacharacters' '\n+\techo content >\"name with \\${meta}\" &&\n+\tgit add \"name with \\${meta}\" &&\n+\tgit commit -m meta &&\n+\ttest_completion \"git show HEAD:nam\" <<-\\EOF\n+\tname with ${meta}Z\n+\tname with spacesZ\n+\tEOF\n+'\n+\n+test_expect_success PERL 'send-email' '\n+\ttest_completion \"git send-email --cov\" <<-\\EOF &&\n+\t--cover-from-description=Z\n+\t--cover-letter Z\n+\tEOF\n+\ttest_completion \"git send-email --val\" <<-\\EOF &&\n+\t--validate Z\n+\tEOF\n+\ttest_completion \"git send-email ma\" \"main \"\n+'\n+\n+test_expect_success 'complete files' '\n+\tgit init tmp && cd tmp &&\n+\ttest_when_finished \"cd .. && rm -rf tmp\" &&\n+\n+\techo \"expected\" > .gitignore &&\n+\techo \"out\" >> .gitignore &&\n+\techo \"out_sorted\" >> .gitignore &&\n+\n+\tgit add .gitignore &&\n+\ttest_completion \"git commit \" \".gitignore\" &&\n+\n+\tgit commit -m ignore &&\n+\n+\ttouch new &&\n+\ttest_completion \"git add \" \"new\" &&\n+\n+\tgit add new &&\n+\tgit commit -a -m new &&\n+\ttest_completion \"git add \" \"\" &&\n+\n+\tgit mv new modified &&\n+\techo modify > modified &&\n+\ttest_completion \"git add \" \"modified\" &&\n+\n+\tmkdir -p some/deep &&\n+\ttouch some/deep/path &&\n+\ttest_completion \"git add some/\" \"some/deep\" &&\n+\tgit clean -f some &&\n+\n+\ttouch untracked &&\n+\n+\t: TODO .gitignore should not be here &&\n+\ttest_completion \"git rm \" <<-\\EOF &&\n+\t.gitignore\n+\tmodified\n+\tEOF\n+\n+\ttest_completion \"git clean \" \"untracked\" &&\n+\n+\t: TODO .gitignore should not be here &&\n+\ttest_completion \"git mv \" <<-\\EOF &&\n+\t.gitignore\n+\tmodified\n+\tEOF\n+\n+\tmkdir dir &&\n+\ttouch dir/file-in-dir &&\n+\tgit add dir/file-in-dir &&\n+\tgit commit -m dir &&\n+\n+\tmkdir untracked-dir &&\n+\n+\t: TODO .gitignore should not be here &&\n+\ttest_completion \"git mv modified \" <<-\\EOF &&\n+\t.gitignore\n+\tdir\n+\tmodified\n+\tuntracked\n+\tuntracked-dir\n+\tEOF\n+\n+\ttest_completion \"git commit \" \"modified\" &&\n+\n+\t: TODO .gitignore should not be here &&\n+\ttest_completion \"git ls-files \" <<-\\EOF &&\n+\t.gitignore\n+\tdir\n+\tmodified\n+\tEOF\n+\n+\ttouch momified &&\n+\ttest_completion \"git add mom\" \"momified\"\n+'\n+\n+test_expect_success \"simple alias\" '\n+\ttest_config alias.co checkout &&\n+\ttest_completion \"git co m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_success \"recursive alias\" '\n+\ttest_config alias.co checkout &&\n+\ttest_config alias.cod \"co --detached\" &&\n+\ttest_completion \"git cod m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_success \"completion uses <cmd> completion for alias: !sh -c 'git <cmd> ...'\" '\n+\ttest_config alias.co \"!sh -c '\"'\"'git checkout ...'\"'\"'\" &&\n+\ttest_completion \"git co m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_success 'completion uses <cmd> completion for alias: !f () { VAR=val git <cmd> ... }' '\n+\ttest_config alias.co \"!f () { VAR=val git checkout ... ; } f\" &&\n+\ttest_completion \"git co m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_success 'completion used <cmd> completion for alias: !f() { : git <cmd> ; ... }' '\n+\ttest_config alias.co \"!f() { : git checkout ; if ... } f\" &&\n+\ttest_completion \"git co m\" <<-\\EOF\n+\tmain Z\n+\tmybranch Z\n+\tmytag Z\n+\tEOF\n+'\n+\n+test_expect_failure 'completion without explicit _git_xxx function' '\n+\ttest_completion \"git version --\" <<-\\EOF\n+\t--build-options Z\n+\t--no-build-options Z\n+\tEOF\n+'\n+\n+test_expect_failure 'complete with tilde expansion' '\n+\tgit init tmp && cd tmp &&\n+\ttest_when_finished \"cd .. && rm -rf tmp\" &&\n+\n+\ttouch ~/tmp/file &&\n+\n+\ttest_completion \"git add ~/tmp/\" \"~/tmp/file\"\n+'\n+\n+test_expect_success 'setup other remote for remote reference completion' '\n+\tgit remote add other otherrepo &&\n+\tgit fetch other\n+'\n+\n+test_expect_success 'git config - section' '\n+\ttest_completion \"git config br\" <<-\\EOF\n+\tbranch.Z\n+\tbrowser.Z\n+\tEOF\n+'\n+\n+test_expect_success 'git config - section include, includeIf' '\n+\ttest_completion \"git config inclu\" <<-\\EOF\n+\tinclude.Z\n+\tincludeIf.Z\n+\tEOF\n+'\n+\n+test_expect_success 'git config - variable name' '\n+\ttest_completion \"git config log.d\" <<-\\EOF\n+\tlog.date Z\n+\tlog.decorate Z\n+\tlog.diffMerges Z\n+\tEOF\n+'\n+\n+test_expect_success 'git config - variable name include' '\n+\ttest_completion \"git config include.p\" <<-\\EOF\n+\tinclude.path Z\n+\tEOF\n+'\n+\n+test_expect_success 'git config - value' '\n+\ttest_completion \"git config color.pager \" <<-\\EOF\n+\tfalse Z\n+\ttrue Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git -c - section' '\n+\ttest_completion \"git -c br\" <<-\\EOF\n+\tbranch.Z\n+\tbrowser.Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git -c - variable name' '\n+\ttest_completion \"git -c log.d\" <<-\\EOF\n+\tlog.date=Z\n+\tlog.decorate=Z\n+\tlog.diffMerges=Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git -c - value' '\n+\ttest_completion \"git -c color.pager=\" <<-\\EOF\n+\tfalse Z\n+\ttrue Z\n+\tEOF\n+'\n+\n+test_expect_success 'git clone --config= - section' '\n+\ttest_completion \"git clone --config=br\" <<-\\EOF\n+\tbranch.Z\n+\tbrowser.Z\n+\tEOF\n+'\n+\n+test_expect_failure 'git clone --config= - variable name' '\n+\ttest_completion \"git clone --config=log.d\" <<-\\EOF\n+\tlog.date=Z\n+\tlog.decorate=Z\n+\tlog.diffMerges=Z\n+\tEOF\n+'\n+\n+test_expect_success 'git clone --config= - value' '\n+\ttest_completion \"git clone --config=color.pager=\" <<-\\EOF\n+\tfalse Z\n+\ttrue Z\n+\tEOF\n+'\n+\n+test_expect_failure 'options with value' '\n+\ttest_completion \"git merge -X diff-algorithm=\" <<-\\EOF\n+\n+\tEOF\n+'\n+\n+test_done\ndiff --git a/t/t9904/.gitignore b/t/t9904/.gitignore\nnew file mode 100644\nindex 0000000000..f9917e1bf9\n--- /dev/null\n+++ b/t/t9904/.gitignore\n@@ -0,0 +1 @@\n+/.zcompdump\ndiff --git a/t/t9904/.zshrc b/t/t9904/.zshrc\nnew file mode 100644\nindex 0000000000..2aec2c9535\n--- /dev/null\n+++ b/t/t9904/.zshrc\n@@ -0,0 +1,51 @@\n+setopt zle\n+setopt list_rows_first\n+\n+PS1=\"<PROMPT>\"\n+fpath=($ZDOTDIR $fpath)\n+LISTMAX=1000\n+\n+autoload -U compinit && compinit -u\n+\n+zstyle ':completion:*:*:git:*' script \"$SRC_DIR/git-completion.bash\"\n+zstyle ':completion:*' list-colors \"no=<MARK>\" \"fi=<MARK>\" \"di=<MARK>\" \"ec=</MARK>\\n\" \"rc=\" \"lc=\" \"sp=\"\n+zstyle ':completion:*' verbose no\n+\n+zle_complete () {\n+\tzle list-choices\n+\tzle kill-whole-line\n+\tprint \"<END-CHOICES>\"\n+}\n+zle -N zle_complete\n+bindkey \"^I\" zle_complete\n+\n+functions[_default]=:\n+\n+compadd () {\n+\tlocal pfx sfx\n+\tlocal -a args\n+\n+\tif (( ${@[(I)-a|-d]} )); then\n+\t\tbuiltin compadd -V unsorted \"$@\"\n+\telse\n+\t\twhile (($#)); do\n+\t\t\tcase \"$1\" in\n+\t\t\t-p) pfx=\"$2\" ; shift 2 ;;\n+\t\t\t-S) sfx=\"$2\" ; shift 2 ;;\n+\t\t\t--) args+=($1) ; shift ; break ;;\n+\t\t\t*) args+=(\"$1\") ; shift ;;\n+\t\t\tesac\n+\t\tdone\n+\n+\t\twhile (($#)); do\n+\t\t\targs+=(${pfx}$1${sfx})\n+\t\t\tshift\n+\t\tdone\n+\n+\t\tbuiltin compadd -V unsorted -S '' \"${args[@]}\"\n+\tfi\n+}\n+\n+_git_func () {\n+\teval ${words[2,-2]}\n+}\ndiff --git a/t/t9904/_git b/t/t9904/_git\nnew file mode 120000\nindex 0000000000..92d0240ac4\n--- /dev/null\n+++ b/t/t9904/_git\n@@ -0,0 +1 @@\n+../../contrib/completion/git-completion.zsh\n\\ No newline at end of file\n-- \n2.40.0\n\n"},{"id":"474548","messageId":"CAPig+cR_F0Xi3qTAJdSs7n3ad545JwHxLmR+xXuNGCB6P460xA@mail.gmail.com","threadId":"59512","inReplyTo":"20230401015632.103581-2-felipe.contreras@gmail.com","subject":"Re: [PATCH 1/2] test: fix build for zsh","fromName":"Eric Sunshine","fromEmail":"sunshine@sunshineco.com","sentAt":"2023-04-01T05:33:34Z","receivedAt":"2023-04-01T05:33:49Z","isPatch":true,"sender":{"key":"sunshine@sunshineco.com","avatar":"https://avatars.githubusercontent.com/u/163641?v=4"},"body":"On Fri, Mar 31, 2023 at 10:16 PM Felipe Contreras\n<felipe.contreras@gmail.com> wrote:\n> zsh has the ability to emulate Bourne shell, which is closer to what our\n> testing suite expect.\n\ns/expect/expects/\n\n> Using the POSIX_ARGZERO option makes $0 behave as POSIX seems to define:\n> show the name of the command launched, as opposed to the zsh default:\n> the path of the script.\n>\n> This enables many tests, but not all.\n>\n> We can run the tests with `zsh --emulate sh` which has more more\n> compatibility, but doing `emulate sh` inside the script allows us to\n> just use `zsh`, although it's not as compatible.\n\ns/more more/more/\n\n> Signed-off-by: Felipe Contreras <felipe.contreras@gmail.com>\n"}]}