{"thread":{"id":"66507","subject":"[PATCH 0/5] stash completion miscellany","startedAt":"2026-10-12T17:48:26Z","lastAt":"2026-10-26T14:30:22Z","messageCount":28,"participants":["D. Ben Knoble","Patrick Steinhardt","Ben Knoble","Kristoffer Haugsbakk","Junio C Hamano"],"isPatch":true,"patchVersion":1,"patchTotal":5},"messages":[{"id":"554781","messageId":"cover.1791827304.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":null,"subject":"[PATCH 0/5] stash completion miscellany","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-12T17:48:26Z","receivedAt":"2026-10-12T17:48:26Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"Hi all,\n\nThis short patch series takes care of a few paper cuts in stash\ncompletion. The first patch is a small code cleanup I noticed a while\nback while working on bfc1b34859 (completion: add stash import, export,\n2026-02-07), I think. The next 2 take care of a problem I've been having\nwith Zsh's completion of stashes (cf. Unix & Linux SE [1]).\n\n[1]: https://unix.stackexchange.com/q/807580/301073\n\nThe final 2 are not only about completion; I noticed we were\nspecial-casing save completion, did some digging, and was a bit confused\nby the status of \"git stash save\". So, I figured while I was here I\nwould start a conversation about (a) restoring the git-stash(1) manual\nto it's \"no save\" version and (b) ripping out the special case.\n\nThese last 2 may be controversial, and I'm not particularly attached to\nthem, so if they need to be dropped I won't really complain. OTOH,\nwhat's the point of a deprecated subcommand we still advertise? ;)\n\nGenerated-with: git format-patch @{u}.. -o p\n\n[1/5] completion: simplify stash subcommand completion\n[2/5] completion: extract common stash listing code\n[3/5] completion: fix Zsh handling of stash names\n[4/5] doc: drop usage mentions of \"git stash save\"\n[5/5] completion: drop \"stash save\" completion altogether\n\n Documentation/git-stash.adoc           |  2 --\n builtin/stash.c                        |  1 -\n contrib/completion/git-completion.bash | 22 +++++++++++++---------\n contrib/completion/git-completion.zsh  |  5 +++++\n 4 files changed, 18 insertions(+), 12 deletions(-)\n\n\nbase-commit: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd\n-- \n2.56.0.184.g5a00b4a6e9.dirty\n\n\n"},{"id":"554782","messageId":"d0e461a14a254cae7d15aa6b62deedb4a0ac6deb.1791827304.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1791827304.git.ben.knoble@gmail.com","subject":"[PATCH 1/5] completion: simplify stash subcommand completion","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-12T17:48:27Z","receivedAt":"2026-10-12T17:48:27Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"The stash completion helper contains a hard-coded list of commands, but\ngit-stash provides a mechanism to list such commands\n(--git-completion-helper). The pattern for using it is wrapped by\n__git_resolve_builtins, so use it, bring _git_stash closer in line with\nother completion helpers.\n\nNote that we maintain the \"save\" special case, since it was removed from\ndefault completion in 0eb5a4f911 (completion: stop showing 'save' for\nstash by default, 2018-04-20). We don't have to do anything special with\nthe exclude (3rd) argument to __git_resolve_builtins, though, because\nsave is already marked PARSE_OPT_NOCOMPLETE.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.bash | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c3a49e2e22..d60e85479c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3553,8 +3553,12 @@ _git_sparse_checkout ()\n \n _git_stash ()\n {\n-\tlocal subcommands='push list show apply clear drop pop create branch import export'\n-\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n+\tlocal subcommands subcommand\n+\n+\t__git_resolve_builtins stash\n+\n+\tsubcommands=\"$___git_resolved_builtins\"\n+\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n \n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$((cword - __git_cmd_idx)),$cur\" in\n-- \n2.56.0.184.g5a00b4a6e9.dirty\n\n\n"},{"id":"554783","messageId":"34fd7f793fa21e83d073ee0547d8de150f460fa9.1791827304.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1791827304.git.ben.knoble@gmail.com","subject":"[PATCH 2/5] completion: extract common stash listing code","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-12T17:48:28Z","receivedAt":"2026-10-12T17:48:28Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"With no change in behavior, prepare to adjust how stashes are completed\nby centralizing candidate generation.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +++++++----\n 1 file changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex d60e85479c..697fef5462 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3593,20 +3593,23 @@ _git_stash ()\n \t\tif [ $cword -eq $((__git_cmd_idx+2)) ]; then\n \t\t\t__git_complete_refs\n \t\telse\n-\t\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t\t__git_complete_stashes\n \t\tfi\n \t\t;;\n \timport,*)\n \t\t__git_complete_refs\n \t\t;;\n \tshow,*|apply,*|drop,*|pop,*|export,*)\n-\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t__git_complete_stashes\n \t\t;;\n \tesac\n }\n \n+__git_complete_stashes ()\n+{\n+\t__gitcomp_nl \"$(__git stash list | sed -n -e 's/:.*//p')\"\n+}\n+\n _git_submodule ()\n {\n \t__git_has_doubledash && return\n-- \n2.56.0.184.g5a00b4a6e9.dirty\n\n\n"},{"id":"554784","messageId":"3d1cd00dd8456aeaf8259767d9e33b7421aef9c4.1791827304.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1791827304.git.ben.knoble@gmail.com","subject":"[PATCH 3/5] completion: fix Zsh handling of stash names","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-12T17:48:29Z","receivedAt":"2026-10-12T17:48:29Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"When Git completes stashes for Zsh, it eventually invokes something like\nthis (via our redefinition of __gitcomp_nl):\n\n    compadd -Q -S \" \" -p \"\" -- 'stash@{0}' 'stash@{1}' && _ret=0\n\nBecause of -Q, the braces are unquoted, and Zsh will leave us at (for\nexample)\n\n    git stash show stash@{\n                   cursor ^\n\nFrom here, the list-choices widget (on Ctrl-D by default) will show\nstash@{0} and stash@{1}, but the complete-word widget (Tab) will just\nadd another brace. Zsh things we're trying to do a brace expansion, I\nthink! Interestingly, using menu-complete (Ctrl-N) does cycle through\nmatches, since it's taking a slightly different completion path in Zsh.\n\nWe might try to fix this by passing surrounding single quotes (using the\n-S/-p arguments of compadd, which we can do via __gitcomp_nl's other\nparameters), and indeed Zsh will generate\n\n    git stash show 'stash@{\n                    cursor ^\n\nbut completing here won't find anything, and I'm not totally sure why.\n\nInstead, though, we can let Zsh quote metacharacters (removing -Q) and\neverything \"just works.\" It changes the output format a bit (users see\nstash@\\{0\\}, for example), but I find this an improvement over not being\nable to complete names at all. menu-complete is unchanged aside from the\nextra backslashes.\n\nSo, override stash listing completion in Zsh with a working version.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.zsh | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex d5c526665b..2aea7770d2 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -135,6 +135,11 @@ __gitcomp_file_direct ()\n \t__gitcomp_file \"$1\" \"\"\n }\n \n+__git_complete_stashes ()\n+{\n+\tcompadd -S ' ' -- ${(f)\"$(__git stash list | sed -n -e 's/:.*//p')\"} && _ret=0\n+}\n+\n _git_zsh ()\n {\n \t__gitcomp \"v1.1\"\n-- \n2.56.0.184.g5a00b4a6e9.dirty\n\n\n"},{"id":"554785","messageId":"5a2ea087bf35a15760206e2c8ea1f8df5a43296a.1791827304.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1791827304.git.ben.knoble@gmail.com","subject":"[PATCH 4/5] doc: drop usage mentions of \"git stash save\"","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-12T17:48:30Z","receivedAt":"2026-10-12T17:48:30Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"Even though we previously deprecated it in fd2ebf14db (stash: mark \"git\nstash save\" deprecated in the man page, 2017-10-22), the save subcommand\nclings to life. For example, 951ec747d4 (doc txt & -h consistency: make\n\"stash\" consistent, 2022-10-13) brought back \"save\" to the git-stash(1)\nsynopsis, and 41a28eb6c1 (stash: implement '--staged' option for 'push'\nand 'save', 2021-10-18) gave it new options. But we really discourage\nits use in modern Git, so let's drop mention of it from -h usage and the\nsynopsis.\n\nIt's still described in the manual, since some descriptions talk about\nthe \"save\" command. As we haven't gone ahead with a full deprecation and\nremoval, we can leave these pieces for folks whose fingers still type\n\"save\" and need a reference for its behavior.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n\nNotes (benknoble/commits):\n    AFAICT there was no discussion of its deprecation when re-adding save to\n    the documentation, so I wonder if that was just an oversight.\n\n Documentation/git-stash.adoc | 2 --\n builtin/stash.c              | 1 -\n 2 files changed, 3 deletions(-)\n\ndiff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc\nindex d6e8c4144c..6bf510702b 100644\n--- a/Documentation/git-stash.adoc\n+++ b/Documentation/git-stash.adoc\n@@ -18,8 +18,6 @@ git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | -\n \t     [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]\n \t     [--pathspec-from-file=<file> [--pathspec-file-nul]]\n \t     [--] [<pathspec>...]\n-git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n-           [-u | --include-untracked] [-a | --all] [<message>]\n git stash clear\n git stash create [<message>]\n git stash store [(-m | --message) <message>] [-q | --quiet] <commit>\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 7a9843413b..94869c2429 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -75,7 +75,6 @@ static const char * const git_stash_usage[] = {\n \tBUILTIN_STASH_APPLY_USAGE,\n \tBUILTIN_STASH_BRANCH_USAGE,\n \tBUILTIN_STASH_PUSH_USAGE,\n-\tBUILTIN_STASH_SAVE_USAGE,\n \tBUILTIN_STASH_CLEAR_USAGE,\n \tBUILTIN_STASH_CREATE_USAGE,\n \tBUILTIN_STASH_STORE_USAGE,\n-- \n2.56.0.184.g5a00b4a6e9.dirty\n\n\n"},{"id":"554786","messageId":"4d228e79bb23c6c4a9b2996a3c8cf55efdeda7c0.1791827304.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1791827304.git.ben.knoble@gmail.com","subject":"[PATCH 5/5] completion: drop \"stash save\" completion altogether","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-12T17:48:31Z","receivedAt":"2026-10-12T17:48:31Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\ndeprecated in the man page, 2017-10-22) and the previous commit removed\nfurther documentation suggesting to use it.\n\nSince we recommend push instead, stop completing for \"save\" and remove a\nspecial case in completion code.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.bash | 5 +----\n 1 file changed, 1 insertion(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 697fef5462..9cd9c7cadb 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3558,16 +3558,13 @@ _git_stash ()\n \t__git_resolve_builtins stash\n \n \tsubcommands=\"$___git_resolved_builtins\"\n-\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n+\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$((cword - __git_cmd_idx)),$cur\" in\n \t\t*,--*)\n \t\t\t__gitcomp_builtin stash_push\n \t\t\t;;\n-\t\t1,sa*)\n-\t\t\t__gitcomp \"save\"\n-\t\t\t;;\n \t\t1,*)\n \t\t\t__gitcomp \"$subcommands\"\n \t\t\t;;\n-- \n2.56.0.184.g5a00b4a6e9.dirty\n\n\n"},{"id":"555217","messageId":"atHZvexnI0Ia7Xjr@pks.im","threadId":"66507","inReplyTo":"3d1cd00dd8456aeaf8259767d9e33b7421aef9c4.1791827304.git.ben.knoble@gmail.com","subject":"Re: [PATCH 3/5] completion: fix Zsh handling of stash names","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-16T08:01:01Z","receivedAt":"2026-10-16T08:01:01Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 12, 2026 at 01:48:29PM -0400, D. Ben Knoble wrote:\n> When Git completes stashes for Zsh, it eventually invokes something like\n> this (via our redefinition of __gitcomp_nl):\n> \n>     compadd -Q -S \" \" -p \"\" -- 'stash@{0}' 'stash@{1}' && _ret=0\n> \n> Because of -Q, the braces are unquoted, and Zsh will leave us at (for\n> example)\n> \n>     git stash show stash@{\n>                    cursor ^\n> \n> From here, the list-choices widget (on Ctrl-D by default) will show\n> stash@{0} and stash@{1}, but the complete-word widget (Tab) will just\n> add another brace. Zsh things we're trying to do a brace expansion, I\n\ns/things/thinks/\n\n> think! Interestingly, using menu-complete (Ctrl-N) does cycle through\n> matches, since it's taking a slightly different completion path in Zsh.\n> \n> We might try to fix this by passing surrounding single quotes (using the\n> -S/-p arguments of compadd, which we can do via __gitcomp_nl's other\n> parameters), and indeed Zsh will generate\n> \n>     git stash show 'stash@{\n>                     cursor ^\n> \n> but completing here won't find anything, and I'm not totally sure why.\n> \n> Instead, though, we can let Zsh quote metacharacters (removing -Q) and\n> everything \"just works.\" It changes the output format a bit (users see\n> stash@\\{0\\}, for example), but I find this an improvement over not being\n> able to complete names at all. menu-complete is unchanged aside from the\n> extra backslashes.\n> \n> So, override stash listing completion in Zsh with a working version.\n\nHm. I assume you tried finding a variant that works for both Bash and\nZsh so that we don't have to carry this override?\n\n> diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\n> index d5c526665b..2aea7770d2 100644\n> --- a/contrib/completion/git-completion.zsh\n> +++ b/contrib/completion/git-completion.zsh\n> @@ -135,6 +135,11 @@ __gitcomp_file_direct ()\n>  \t__gitcomp_file \"$1\" \"\"\n>  }\n>  \n> +__git_complete_stashes ()\n> +{\n> +\tcompadd -S ' ' -- ${(f)\"$(__git stash list | sed -n -e 's/:.*//p')\"} && _ret=0\n> +}\n\nPatrick\n\n"},{"id":"555218","messageId":"atHZyXcGzTQ5GkGm@pks.im","threadId":"66507","inReplyTo":"5a2ea087bf35a15760206e2c8ea1f8df5a43296a.1791827304.git.ben.knoble@gmail.com","subject":"Re: [PATCH 4/5] doc: drop usage mentions of \"git stash save\"","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-16T08:01:13Z","receivedAt":"2026-10-16T08:01:13Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 12, 2026 at 01:48:30PM -0400, D. Ben Knoble wrote:\n> Even though we previously deprecated it in fd2ebf14db (stash: mark \"git\n> stash save\" deprecated in the man page, 2017-10-22), the save subcommand\n> clings to life. For example, 951ec747d4 (doc txt & -h consistency: make\n\nHeh :)\n\n> \"stash\" consistent, 2022-10-13) brought back \"save\" to the git-stash(1)\n> synopsis, and 41a28eb6c1 (stash: implement '--staged' option for 'push'\n> and 'save', 2021-10-18) gave it new options. But we really discourage\n> its use in modern Git, so let's drop mention of it from -h usage and the\n> synopsis.\n> \n> It's still described in the manual, since some descriptions talk about\n> the \"save\" command. As we haven't gone ahead with a full deprecation and\n> removal, we can leave these pieces for folks whose fingers still type\n> \"save\" and need a reference for its behavior.\n\nI was wondering why we still have the command as part of our synopsis in\ncase it's deprecated, so good that you address this, too.\n\n> Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n> ---\n> \n> Notes (benknoble/commits):\n>     AFAICT there was no discussion of its deprecation when re-adding save to\n>     the documentation, so I wonder if that was just an oversight.\n\nI bet. In any case, I agree with removing it from our synopsis again.\n\nPatrick\n\n"},{"id":"555219","messageId":"atHZzrybhYzMVGbQ@pks.im","threadId":"66507","inReplyTo":"d0e461a14a254cae7d15aa6b62deedb4a0ac6deb.1791827304.git.ben.knoble@gmail.com","subject":"Re: [PATCH 1/5] completion: simplify stash subcommand completion","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-16T08:01:18Z","receivedAt":"2026-10-16T08:01:18Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 12, 2026 at 01:48:27PM -0400, D. Ben Knoble wrote:\n> The stash completion helper contains a hard-coded list of commands, but\n> git-stash provides a mechanism to list such commands\n> (--git-completion-helper). The pattern for using it is wrapped by\n> __git_resolve_builtins, so use it, bring _git_stash closer in line with\n\ns/bring/bringing/?\n\n> other completion helpers.\n> \n> Note that we maintain the \"save\" special case, since it was removed from\n> default completion in 0eb5a4f911 (completion: stop showing 'save' for\n> stash by default, 2018-04-20). We don't have to do anything special with\n> the exclude (3rd) argument to __git_resolve_builtins, though, because\n> save is already marked PARSE_OPT_NOCOMPLETE.\n\nI didn't understand the last sentence without going into the code.\n\nI assume what you want to say is that we don't have to explicitly\nexclude it when completing the subcommand because it's already marked as\nNOCOMPLETE. But we don't want to fully ignore it, either, because we\nwant to be able to complete that subcommand if the user explicitly wrote\nit?\n\nSo basically: we're not completing it if the user writes \"git stash\nsa<TAB>\", but we then know to complete its options if the user writes\n\"git stash save --<TAB>\". Which I guess makes sense for a deprecated\nsubcommand.\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index c3a49e2e22..d60e85479c 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -3553,8 +3553,12 @@ _git_sparse_checkout ()\n>  \n>  _git_stash ()\n>  {\n> -\tlocal subcommands='push list show apply clear drop pop create branch import export'\n> -\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n> +\tlocal subcommands subcommand\n> +\n> +\t__git_resolve_builtins stash\n> +\n> +\tsubcommands=\"$___git_resolved_builtins\"\n> +\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n\nMore plumbing, but less stuff that we need to keep up-to-date. This also\nfixes that the \"store\" subcommand wasn't completed, which should\nprobably be pointed out in the commit message.\n\nPatrick\n\n"},{"id":"555220","messageId":"atHZ0gV5Pz80l3ho@pks.im","threadId":"66507","inReplyTo":"4d228e79bb23c6c4a9b2996a3c8cf55efdeda7c0.1791827304.git.ben.knoble@gmail.com","subject":"Re: [PATCH 5/5] completion: drop \"stash save\" completion altogether","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-16T08:01:22Z","receivedAt":"2026-10-16T08:01:22Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:\n> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n> deprecated in the man page, 2017-10-22) and the previous commit removed\n> further documentation suggesting to use it.\n> \n> Since we recommend push instead, stop completing for \"save\" and remove a\n> special case in completion code.\n\nThis is the only part I'm a bit torn on. I think it's reasonable to not\nautocomplete the \"save\" command, but if the user manually types it,\nshould we really stop autocompleting its options altogether?\n\nMaybe the answer is \"yes\". After all, as you mentioned in the preceding\ncommit, the command is deprecated since 2017 already! And after almost\n10 years I think it's fair to start giving users more nudges into the\ndirection of using \"push\" instead.\n\nOne note though: the command _will_ be completed in the case where you\nhave GIT_COMPLETION_SHOW_ALL set.\n\nPatrick\n\n"},{"id":"555453","messageId":"841E7396-646B-4667-84C8-A51BDD7371F2@gmail.com","threadId":"66507","inReplyTo":"atHZvexnI0Ia7Xjr@pks.im","subject":"Re: [PATCH 3/5] completion: fix Zsh handling of stash names","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-19T19:56:18Z","receivedAt":"2026-10-19T19:56:18Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :\n> \n> ﻿On Mon, Oct 12, 2026 at 01:48:29PM -0400, D. Ben Knoble wrote:\n>> When Git completes stashes for Zsh, it eventually invokes something like\n>> this (via our redefinition of __gitcomp_nl):\n>> \n>>    compadd -Q -S \" \" -p \"\" -- 'stash@{0}' 'stash@{1}' && _ret=0\n>> \n>> Because of -Q, the braces are unquoted, and Zsh will leave us at (for\n>> example)\n>> \n>>    git stash show stash@{\n>>                   cursor ^\n>> \n>> From here, the list-choices widget (on Ctrl-D by default) will show\n>> stash@{0} and stash@{1}, but the complete-word widget (Tab) will just\n>> add another brace. Zsh things we're trying to do a brace expansion, I\n> \n> s/things/thinks/\n\nWill fix!\n\n>> think! Interestingly, using menu-complete (Ctrl-N) does cycle through\n>> matches, since it's taking a slightly different completion path in Zsh.\n>> \n>> We might try to fix this by passing surrounding single quotes (using the\n>> -S/-p arguments of compadd, which we can do via __gitcomp_nl's other\n>> parameters), and indeed Zsh will generate\n>> \n>>    git stash show 'stash@{\n>>                    cursor ^\n>> \n>> but completing here won't find anything, and I'm not totally sure why.\n>> \n>> Instead, though, we can let Zsh quote metacharacters (removing -Q) and\n>> everything \"just works.\" It changes the output format a bit (users see\n>> stash@\\{0\\}, for example), but I find this an improvement over not being\n>> able to complete names at all. menu-complete is unchanged aside from the\n>> extra backslashes.\n>> \n>> So, override stash listing completion in Zsh with a working version.\n> \n> Hm. I assume you tried finding a variant that works for both Bash and\n> Zsh so that we don't have to carry this override?\n\nActually, no. I assumed Bash was working and haven’t tested it either way.\nPresumably we’d have a report from someone if it were doing what Zsh does?\n\nMany Zsh users, OTOH, use the Zsh-distributed completions,\nwhich stackoverflow for me (and anyway I prefer ours).\n\nI won’t have time to see if Bash is also Brien here, but this shouldn’t\nchange Bash’s behavior at least.\n\nOh, re-reading: yes, I looked for something that was compatible\nwith existing code. I mentioned one such attempt (single quotes).\nNo luck, though.\n"},{"id":"555454","messageId":"2076548D-473E-4EC7-AE92-3DCBF1D3A4F1@gmail.com","threadId":"66507","inReplyTo":"atHZzrybhYzMVGbQ@pks.im","subject":"Re: [PATCH 1/5] completion: simplify stash subcommand completion","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-19T19:58:24Z","receivedAt":"2026-10-19T19:58:24Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :\n> \n> ﻿On Mon, Oct 12, 2026 at 01:48:27PM -0400, D. Ben Knoble wrote:\n>> The stash completion helper contains a hard-coded list of commands, but\n>> git-stash provides a mechanism to list such commands\n>> (--git-completion-helper). The pattern for using it is wrapped by\n>> __git_resolve_builtins, so use it, bring _git_stash closer in line with\n> \n> s/bring/bringing/?\n\nWill fix!\n\n>> other completion helpers.\n>> \n>> Note that we maintain the \"save\" special case, since it was removed from\n>> default completion in 0eb5a4f911 (completion: stop showing 'save' for\n>> stash by default, 2018-04-20). We don't have to do anything special with\n>> the exclude (3rd) argument to __git_resolve_builtins, though, because\n>> save is already marked PARSE_OPT_NOCOMPLETE.\n> \n> I didn't understand the last sentence without going into the code.\n> \n> I assume what you want to say is that we don't have to explicitly\n> exclude it when completing the subcommand because it's already marked as\n> NOCOMPLETE. But we don't want to fully ignore it, either, because we\n> want to be able to complete that subcommand if the user explicitly wrote\n> it?\n> \n> So basically: we're not completing it if the user writes \"git stash\n> sa<TAB>\", but we then know to complete its options if the user writes\n> \"git stash save --<TAB>\". Which I guess makes sense for a deprecated\n> subcommand.\n\nCorrect. I got a little too familiar with the completion guts\nwhile working on this. I’ll try reworking it when I get back to v2.\n\n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index c3a49e2e22..d60e85479c 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -3553,8 +3553,12 @@ _git_sparse_checkout ()\n>> \n>> _git_stash ()\n>> {\n>> -    local subcommands='push list show apply clear drop pop create branch import export'\n>> -    local subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n>> +    local subcommands subcommand\n>> +\n>> +    __git_resolve_builtins stash\n>> +\n>> +    subcommands=\"$___git_resolved_builtins\"\n>> +    subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n> \n> More plumbing, but less stuff that we need to keep up-to-date.\n\nAnd more aligned with other helpers, yep.\n\n> This also\n> fixes that the \"store\" subcommand wasn't completed, which should\n> probably be pointed out in the commit message.\n\nI missed that, will add. Thanks!\n"},{"id":"555455","messageId":"35E6B235-6370-4F94-A0B1-4B6A941D8C47@gmail.com","threadId":"66507","inReplyTo":"atHZ0gV5Pz80l3ho@pks.im","subject":"Re: [PATCH 5/5] completion: drop \"stash save\" completion altogether","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-19T20:01:15Z","receivedAt":"2026-10-19T20:01:15Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :\n> \n> ﻿On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:\n>> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n>> deprecated in the man page, 2017-10-22) and the previous commit removed\n>> further documentation suggesting to use it.\n>> \n>> Since we recommend push instead, stop completing for \"save\" and remove a\n>> special case in completion code.\n> \n> This is the only part I'm a bit torn on. I think it's reasonable to not\n> autocomplete the \"save\" command, but if the user manually types it,\n> should we really stop autocompleting its options altogether?\n> \n> Maybe the answer is \"yes\". After all, as you mentioned in the preceding\n> commit, the command is deprecated since 2017 already! And after almost\n> 10 years I think it's fair to start giving users more nudges into the\n> direction of using \"push\" instead.\n> \n> One note though: the command _will_ be completed in the case where you\n> have GIT_COMPLETION_SHOW_ALL set\n\nI should definitely mention SHOW_ALL; I’m not actually sure \nwhat happens for « git stash save --<TAB> » with this patch,\nso I’ll double-check. I actually wonder if it will complete options.\n\nWould that satisfy you if so ?\n"},{"id":"555497","messageId":"atcEqHErXaGiMu4J@pks.im","threadId":"66507","inReplyTo":"35E6B235-6370-4F94-A0B1-4B6A941D8C47@gmail.com","subject":"Re: [PATCH 5/5] completion: drop \"stash save\" completion altogether","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-20T06:05:28Z","receivedAt":"2026-10-20T06:05:28Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Mon, Oct 19, 2026 at 04:01:15PM -0400, Ben Knoble wrote:\n> \n> > Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :\n> > \n> > ﻿On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:\n> >> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n> >> deprecated in the man page, 2017-10-22) and the previous commit removed\n> >> further documentation suggesting to use it.\n> >> \n> >> Since we recommend push instead, stop completing for \"save\" and remove a\n> >> special case in completion code.\n> > \n> > This is the only part I'm a bit torn on. I think it's reasonable to not\n> > autocomplete the \"save\" command, but if the user manually types it,\n> > should we really stop autocompleting its options altogether?\n> > \n> > Maybe the answer is \"yes\". After all, as you mentioned in the preceding\n> > commit, the command is deprecated since 2017 already! And after almost\n> > 10 years I think it's fair to start giving users more nudges into the\n> > direction of using \"push\" instead.\n> > \n> > One note though: the command _will_ be completed in the case where you\n> > have GIT_COMPLETION_SHOW_ALL set\n> \n> I should definitely mention SHOW_ALL; I’m not actually sure \n> what happens for « git stash save --<TAB> » with this patch,\n> so I’ll double-check. I actually wonder if it will complete options.\n> \n> Would that satisfy you if so ?\n\nProbably depends on the outcome of your tests, but ultimately I think\nI'd be fine with either of the options. But if we stop autocompleting we\nshould definitely mention SHOW_ALL.\n\nThanks!\n\nPatrick\n\n"},{"id":"555865","messageId":"CALnO6CCUfja_AxYjbz9xpZgoibbdvy6C4utDDQk9ONhjiOYYzg@mail.gmail.com","threadId":"66507","inReplyTo":"atcEqHErXaGiMu4J@pks.im","subject":"Re: [PATCH 5/5] completion: drop \"stash save\" completion altogether","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-22T13:14:52Z","receivedAt":"2026-10-22T13:14:52Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"On Tue, Oct 20, 2026 at 2:05 AM Patrick Steinhardt <ps@pks.im> wrote:\n>\n> On Mon, Oct 19, 2026 at 04:01:15PM -0400, Ben Knoble wrote:\n> >\n> > > Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :\n> > >\n> > > ﻿On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:\n> > >> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n> > >> deprecated in the man page, 2017-10-22) and the previous commit removed\n> > >> further documentation suggesting to use it.\n> > >>\n> > >> Since we recommend push instead, stop completing for \"save\" and remove a\n> > >> special case in completion code.\n> > >\n> > > This is the only part I'm a bit torn on. I think it's reasonable to not\n> > > autocomplete the \"save\" command, but if the user manually types it,\n> > > should we really stop autocompleting its options altogether?\n> > >\n> > > Maybe the answer is \"yes\". After all, as you mentioned in the preceding\n> > > commit, the command is deprecated since 2017 already! And after almost\n> > > 10 years I think it's fair to start giving users more nudges into the\n> > > direction of using \"push\" instead.\n> > >\n> > > One note though: the command _will_ be completed in the case where you\n> > > have GIT_COMPLETION_SHOW_ALL set\n> >\n> > I should definitely mention SHOW_ALL; I’m not actually sure\n> > what happens for « git stash save --<TAB> » with this patch,\n> > so I’ll double-check. I actually wonder if it will complete options.\n> >\n> > Would that satisfy you if so ?\n>\n> Probably depends on the outcome of your tests, but ultimately I think\n> I'd be fine with either of the options. But if we stop autocompleting we\n> should definitely mention SHOW_ALL.\n\nHere's what my testing showed (all Zsh):\n\n- with SHOW_ALL, \"git stash <tab>\" lists \"save\" as an option; \"git\nstash save --<tab>\" completes options\n- without SHOW_ALL, \"git stash <tab>\" does not list \"save\"; \"git stash\nsa<tab>\" does not complete \"save\"; \"git stash save --<tab>\" completes\noptions\n\nI'll update the commit locally to reflect this. Thoughts?\n\n-- \nD. Ben Knoble\n\n"},{"id":"555950","messageId":"atr81upZrCofQACJ@pks.im","threadId":"66507","inReplyTo":"CALnO6CCUfja_AxYjbz9xpZgoibbdvy6C4utDDQk9ONhjiOYYzg@mail.gmail.com","subject":"Re: [PATCH 5/5] completion: drop \"stash save\" completion altogether","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-23T06:21:10Z","receivedAt":"2026-10-23T06:21:10Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Thu, Oct 22, 2026 at 09:14:52AM -0400, D. Ben Knoble wrote:\n> On Tue, Oct 20, 2026 at 2:05 AM Patrick Steinhardt <ps@pks.im> wrote:\n> >\n> > On Mon, Oct 19, 2026 at 04:01:15PM -0400, Ben Knoble wrote:\n> > >\n> > > > Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :\n> > > >\n> > > > ﻿On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:\n> > > >> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n> > > >> deprecated in the man page, 2017-10-22) and the previous commit removed\n> > > >> further documentation suggesting to use it.\n> > > >>\n> > > >> Since we recommend push instead, stop completing for \"save\" and remove a\n> > > >> special case in completion code.\n> > > >\n> > > > This is the only part I'm a bit torn on. I think it's reasonable to not\n> > > > autocomplete the \"save\" command, but if the user manually types it,\n> > > > should we really stop autocompleting its options altogether?\n> > > >\n> > > > Maybe the answer is \"yes\". After all, as you mentioned in the preceding\n> > > > commit, the command is deprecated since 2017 already! And after almost\n> > > > 10 years I think it's fair to start giving users more nudges into the\n> > > > direction of using \"push\" instead.\n> > > >\n> > > > One note though: the command _will_ be completed in the case where you\n> > > > have GIT_COMPLETION_SHOW_ALL set\n> > >\n> > > I should definitely mention SHOW_ALL; I’m not actually sure\n> > > what happens for « git stash save --<TAB> » with this patch,\n> > > so I’ll double-check. I actually wonder if it will complete options.\n> > >\n> > > Would that satisfy you if so ?\n> >\n> > Probably depends on the outcome of your tests, but ultimately I think\n> > I'd be fine with either of the options. But if we stop autocompleting we\n> > should definitely mention SHOW_ALL.\n> \n> Here's what my testing showed (all Zsh):\n> \n> - with SHOW_ALL, \"git stash <tab>\" lists \"save\" as an option; \"git\n> stash save --<tab>\" completes options\n> - without SHOW_ALL, \"git stash <tab>\" does not list \"save\"; \"git stash\n> sa<tab>\" does not complete \"save\"; \"git stash save --<tab>\" completes\n> options\n> \n> I'll update the commit locally to reflect this. Thoughts?\n\nWe could of course add logic to explicitly stop completing options for\nthe deprecated subcommand. But I doubt it's worth it? So I think this is\ngood enough.\n\nPatrick\n\n"},{"id":"556027","messageId":"cover.1792761643.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1791827304.git.ben.knoble@gmail.com","subject":"[PATCH v2 0/5] stash completion miscellany","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T13:20:50Z","receivedAt":"2026-10-23T13:20:50Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"Hi all,\n\nThis short patch series takes care of a few paper cuts in stash\ncompletion. The first patch is a small code cleanup I noticed a while\nback while working on bfc1b34859 (completion: add stash import, export,\n2026-02-07), I think. The next 2 take care of a problem I've been having\nwith Zsh's completion of stashes (cf. Unix & Linux SE [1]).\n\n[1]: https://unix.stackexchange.com/q/807580/301073\n\nChanges in v2:\n• Reworded a few commit messages thanks to Patrick\n• Clarify the behavior of the final patches with completion for \"git\n  stash save\" (also thanks to Patrick)\n\nThe final 2 are not only about completion; I noticed we were\nspecial-casing save completion, did some digging, and was a bit confused\nby the status of \"git stash save\". So, I figured while I was here I\nwould start a conversation about (a) restoring the git-stash(1) manual\nto it's \"no save\" version and (b) ripping out the special case.\n\nThese last 2 may be controversial, and I'm not particularly attached to\nthem, so if they need to be dropped I won't really complain. OTOH,\nwhat's the point of a deprecated subcommand we still advertise? ;)\n\nGenerated-with: git format-patch @{u}.. -o p -v2 --range-diff=@{u}..d1d0bf2d9a7d380d10771b5d1bceb8db91c5f05e --in-reply-to=cover.1791827304.git.ben.knoble@gmail.com --cc='Patrick Steinhardt <ps@pks.im>'\n\nI accidentally left the above line in v1, but I'm considering leaving it in from\nnow on? It's the exact command I run to generate patches; I store it as a\n\"trailer\" in the branch description, then run \"git generated-with\"† which\n(effectively) does\n\n    eval \"$(git bdesc | git interpret-trailers --parse | grep ^Generated-with | cut -d: -f 2-)\"\n\nwhere \"bdesc\" is an alias for\n\n    git -c core.editor=cat branch --edit-description | git stripspace -s\n\nAnyway, I've been hand-editing them out of cover letters for the last few\nseries, but if it doesn't bother anyone I'll just leave it around. Might be\nhelpful for new folks learning how to format patches?\n\n†: https://github.com/benknoble/Dotfiles/blob/master/links/bin/git-generated-with\n\n[1/5] completion: simplify stash subcommand completion\n[2/5] Completion: extract common stash listing code\n[3/5] completion: fix Zsh handling of stash names\n[4/5] doc: drop usage mentions of \"git stash save\"\n[5/5] completion: drop \"stash save\" completion altogether\n\n Documentation/git-stash.adoc           |  2 --\n builtin/stash.c                        |  1 -\n contrib/completion/git-completion.bash | 22 +++++++++++++---------\n contrib/completion/git-completion.zsh  |  5 +++++\n 4 files changed, 18 insertions(+), 12 deletions(-)\n\nDiff-intervalle contre v1 :\n1:  d0e461a14a ! 1:  90d36b6445 completion: simplify stash subcommand completion\n    @@ Commit message\n         The stash completion helper contains a hard-coded list of commands, but\n         git-stash provides a mechanism to list such commands\n         (--git-completion-helper). The pattern for using it is wrapped by\n    -    __git_resolve_builtins, so use it, bring _git_stash closer in line with\n    -    other completion helpers.\n    +    __git_resolve_builtins, so use it, bringing _git_stash closer in line\n    +    with other completion helpers. As a nice side-benefit, this also adds\n    +    \"store\" subcommand completion, which is missing from the explicit list\n    +    of subcommands.\n     \n    -    Note that we maintain the \"save\" special case, since it was removed from\n    +    Note that we maintain the \"save\" special case†, since it was removed from\n         default completion in 0eb5a4f911 (completion: stop showing 'save' for\n    -    stash by default, 2018-04-20). We don't have to do anything special with\n    -    the exclude (3rd) argument to __git_resolve_builtins, though, because\n    -    save is already marked PARSE_OPT_NOCOMPLETE.\n    +    stash by default, 2018-04-20). One might think we need to give \"save\" to\n    +    __git_resolve_builtins' 3rd exclude argument to prevent it from\n    +    showing up, but we don't: \"save\" is already marked PARSE_OPT_NOCOMPLETE.\n    +\n    +    †We don't complete the \"save\" subcommand unless at least \"sa\" has been\n    +    typed, but we do complete its options if explicitly typed. With this\n    +    change, we will complete \"save\" if GIT_COMPLETION_SHOW_ALL=1.\n     \n      ## contrib/completion/git-completion.bash ##\n     @@ contrib/completion/git-completion.bash: _git_sparse_checkout ()\n2:  6c24a833fc = 2:  abf8efb792 Completion: extract common stash listing code\n3:  22283a1d5f ! 3:  f4f6b89ff6 completion: fix Zsh handling of stash names\n    @@ Commit message\n     \n         From here, the list-choices widget (on Ctrl-D by default) will show\n         stash@{0} and stash@{1}, but the complete-word widget (Tab) will just\n    -    add another brace. Zsh things we're trying to do a brace expansion, I\n    +    add another brace. Zsh thinks we're trying to do a brace expansion, I\n         think! Interestingly, using menu-complete (Ctrl-N) does cycle through\n         matches, since it's taking a slightly different completion path in Zsh.\n     \n         We might try to fix this by passing surrounding single quotes (using the\n    -    -S/-p arguments of compadd, which we can do via __gitcomp_nl's other\n    -    parameters), and indeed Zsh will generate\n    +    -S/-p arguments of compadd, which we can do from Bash in our code via\n    +    __gitcomp_nl's other parameters), and indeed Zsh will generate\n     \n             git stash show 'stash@{\n                             cursor ^\n4:  985a14f18e = 4:  3762f9d5bb doc: drop usage mentions of \"git stash save\"\n5:  d1d0bf2d9a ! 5:  0266646fb4 completion: drop \"stash save\" completion altogether\n    @@ Commit message\n         further documentation suggesting to use it.\n     \n         Since we recommend push instead, stop completing for \"save\" and remove a\n    -    special case in completion code.\n    +    special case in completion code. It still appears for \"git stash <tab>\"\n    +    when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still\n    +    complete options for\n    +\n    +        git stash save --<tab>\n    +\n    +    which is helpful for folks with finger-memory for save.\n     \n      ## contrib/completion/git-completion.bash ##\n     @@ contrib/completion/git-completion.bash: _git_stash ()\n\nbase-commit: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd\n-- \n2.56.0.237.g5414b88716.dirty\n\n\n"},{"id":"556028","messageId":"90d36b64450a21e9afed62c66fd3f72e4c4d429f.1792761643.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"[PATCH v2 1/5] completion: simplify stash subcommand completion","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T13:20:51Z","receivedAt":"2026-10-23T13:20:51Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"The stash completion helper contains a hard-coded list of commands, but\ngit-stash provides a mechanism to list such commands\n(--git-completion-helper). The pattern for using it is wrapped by\n__git_resolve_builtins, so use it, bringing _git_stash closer in line\nwith other completion helpers. As a nice side-benefit, this also adds\n\"store\" subcommand completion, which is missing from the explicit list\nof subcommands.\n\nNote that we maintain the \"save\" special case†, since it was removed from\ndefault completion in 0eb5a4f911 (completion: stop showing 'save' for\nstash by default, 2018-04-20). One might think we need to give \"save\" to\n__git_resolve_builtins' 3rd exclude argument to prevent it from\nshowing up, but we don't: \"save\" is already marked PARSE_OPT_NOCOMPLETE.\n\n†We don't complete the \"save\" subcommand unless at least \"sa\" has been\ntyped, but we do complete its options if explicitly typed. With this\nchange, we will complete \"save\" if GIT_COMPLETION_SHOW_ALL=1.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.bash | 8 ++++++--\n 1 file changed, 6 insertions(+), 2 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex c3a49e2e22..d60e85479c 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3553,8 +3553,12 @@ _git_sparse_checkout ()\n \n _git_stash ()\n {\n-\tlocal subcommands='push list show apply clear drop pop create branch import export'\n-\tlocal subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n+\tlocal subcommands subcommand\n+\n+\t__git_resolve_builtins stash\n+\n+\tsubcommands=\"$___git_resolved_builtins\"\n+\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n \n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$((cword - __git_cmd_idx)),$cur\" in\n-- \n2.56.0.237.g5414b88716.dirty\n\n\n"},{"id":"556029","messageId":"abf8efb792e6cc90db2752baaef4a7bb1d00f4b1.1792761643.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"[PATCH v2 2/5] Completion: extract common stash listing code","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T13:20:52Z","receivedAt":"2026-10-23T13:20:52Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"With no change in behavior, prepare to adjust how stashes are completed\nby centralizing candidate generation.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.bash | 11 +++++++----\n 1 file changed, 7 insertions(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex d60e85479c..697fef5462 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3593,20 +3593,23 @@ _git_stash ()\n \t\tif [ $cword -eq $((__git_cmd_idx+2)) ]; then\n \t\t\t__git_complete_refs\n \t\telse\n-\t\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t\t__git_complete_stashes\n \t\tfi\n \t\t;;\n \timport,*)\n \t\t__git_complete_refs\n \t\t;;\n \tshow,*|apply,*|drop,*|pop,*|export,*)\n-\t\t__gitcomp_nl \"$(__git stash list \\\n-\t\t\t\t| sed -n -e 's/:.*//p')\"\n+\t\t__git_complete_stashes\n \t\t;;\n \tesac\n }\n \n+__git_complete_stashes ()\n+{\n+\t__gitcomp_nl \"$(__git stash list | sed -n -e 's/:.*//p')\"\n+}\n+\n _git_submodule ()\n {\n \t__git_has_doubledash && return\n-- \n2.56.0.237.g5414b88716.dirty\n\n\n"},{"id":"556030","messageId":"f4f6b89ff6584e3d5dcc8a0ade81e05d3203a55f.1792761643.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"[PATCH v2 3/5] completion: fix Zsh handling of stash names","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T13:20:53Z","receivedAt":"2026-10-23T13:20:53Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"When Git completes stashes for Zsh, it eventually invokes something like\nthis (via our redefinition of __gitcomp_nl):\n\n    compadd -Q -S \" \" -p \"\" -- 'stash@{0}' 'stash@{1}' && _ret=0\n\nBecause of -Q, the braces are unquoted, and Zsh will leave us at (for\nexample)\n\n    git stash show stash@{\n                   cursor ^\n\nFrom here, the list-choices widget (on Ctrl-D by default) will show\nstash@{0} and stash@{1}, but the complete-word widget (Tab) will just\nadd another brace. Zsh thinks we're trying to do a brace expansion, I\nthink! Interestingly, using menu-complete (Ctrl-N) does cycle through\nmatches, since it's taking a slightly different completion path in Zsh.\n\nWe might try to fix this by passing surrounding single quotes (using the\n-S/-p arguments of compadd, which we can do from Bash in our code via\n__gitcomp_nl's other parameters), and indeed Zsh will generate\n\n    git stash show 'stash@{\n                    cursor ^\n\nbut completing here won't find anything, and I'm not totally sure why.\n\nInstead, though, we can let Zsh quote metacharacters (removing -Q) and\neverything \"just works.\" It changes the output format a bit (users see\nstash@\\{0\\}, for example), but I find this an improvement over not being\nable to complete names at all. menu-complete is unchanged aside from the\nextra backslashes.\n\nSo, override stash listing completion in Zsh with a working version.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.zsh | 5 +++++\n 1 file changed, 5 insertions(+)\n\ndiff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh\nindex d5c526665b..2aea7770d2 100644\n--- a/contrib/completion/git-completion.zsh\n+++ b/contrib/completion/git-completion.zsh\n@@ -135,6 +135,11 @@ __gitcomp_file_direct ()\n \t__gitcomp_file \"$1\" \"\"\n }\n \n+__git_complete_stashes ()\n+{\n+\tcompadd -S ' ' -- ${(f)\"$(__git stash list | sed -n -e 's/:.*//p')\"} && _ret=0\n+}\n+\n _git_zsh ()\n {\n \t__gitcomp \"v1.1\"\n-- \n2.56.0.237.g5414b88716.dirty\n\n\n"},{"id":"556031","messageId":"3762f9d5bbe4096ee2704992749381627fdc4474.1792761643.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"[PATCH v2 4/5] doc: drop usage mentions of \"git stash save\"","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T13:20:54Z","receivedAt":"2026-10-23T13:20:54Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"Even though we previously deprecated it in fd2ebf14db (stash: mark \"git\nstash save\" deprecated in the man page, 2017-10-22), the save subcommand\nclings to life. For example, 951ec747d4 (doc txt & -h consistency: make\n\"stash\" consistent, 2022-10-13) brought back \"save\" to the git-stash(1)\nsynopsis, and 41a28eb6c1 (stash: implement '--staged' option for 'push'\nand 'save', 2021-10-18) gave it new options. But we really discourage\nits use in modern Git, so let's drop mention of it from -h usage and the\nsynopsis.\n\nIt's still described in the manual, since some descriptions talk about\nthe \"save\" command. As we haven't gone ahead with a full deprecation and\nremoval, we can leave these pieces for folks whose fingers still type\n\"save\" and need a reference for its behavior.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n Documentation/git-stash.adoc | 2 --\n builtin/stash.c              | 1 -\n 2 files changed, 3 deletions(-)\n\ndiff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc\nindex d6e8c4144c..6bf510702b 100644\n--- a/Documentation/git-stash.adoc\n+++ b/Documentation/git-stash.adoc\n@@ -18,8 +18,6 @@ git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | -\n \t     [-u | --include-untracked] [-a | --all] [(-m | --message) <message>]\n \t     [--pathspec-from-file=<file> [--pathspec-file-nul]]\n \t     [--] [<pathspec>...]\n-git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]\n-           [-u | --include-untracked] [-a | --all] [<message>]\n git stash clear\n git stash create [<message>]\n git stash store [(-m | --message) <message>] [-q | --quiet] <commit>\ndiff --git a/builtin/stash.c b/builtin/stash.c\nindex 7a9843413b..94869c2429 100644\n--- a/builtin/stash.c\n+++ b/builtin/stash.c\n@@ -75,7 +75,6 @@ static const char * const git_stash_usage[] = {\n \tBUILTIN_STASH_APPLY_USAGE,\n \tBUILTIN_STASH_BRANCH_USAGE,\n \tBUILTIN_STASH_PUSH_USAGE,\n-\tBUILTIN_STASH_SAVE_USAGE,\n \tBUILTIN_STASH_CLEAR_USAGE,\n \tBUILTIN_STASH_CREATE_USAGE,\n \tBUILTIN_STASH_STORE_USAGE,\n-- \n2.56.0.237.g5414b88716.dirty\n\n\n"},{"id":"556032","messageId":"0266646fb4e6eb4932ec728ce425af9886e5f146.1792761643.git.ben.knoble@gmail.com","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"[PATCH v2 5/5] completion: drop \"stash save\" completion altogether","fromName":"D. Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T13:20:55Z","receivedAt":"2026-10-23T13:20:55Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\ndeprecated in the man page, 2017-10-22) and the previous commit removed\nfurther documentation suggesting to use it.\n\nSince we recommend push instead, stop completing for \"save\" and remove a\nspecial case in completion code. It still appears for \"git stash <tab>\"\nwhen GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still\ncomplete options for\n\n    git stash save --<tab>\n\nwhich is helpful for folks with finger-memory for save.\n\nSigned-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n---\n contrib/completion/git-completion.bash | 5 +----\n 1 file changed, 1 insertion(+), 4 deletions(-)\n\ndiff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\nindex 697fef5462..9cd9c7cadb 100644\n--- a/contrib/completion/git-completion.bash\n+++ b/contrib/completion/git-completion.bash\n@@ -3558,16 +3558,13 @@ _git_stash ()\n \t__git_resolve_builtins stash\n \n \tsubcommands=\"$___git_resolved_builtins\"\n-\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n+\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n \n \tif [ -z \"$subcommand\" ]; then\n \t\tcase \"$((cword - __git_cmd_idx)),$cur\" in\n \t\t*,--*)\n \t\t\t__gitcomp_builtin stash_push\n \t\t\t;;\n-\t\t1,sa*)\n-\t\t\t__gitcomp \"save\"\n-\t\t\t;;\n \t\t1,*)\n \t\t\t__gitcomp \"$subcommands\"\n \t\t\t;;\n-- \n2.56.0.237.g5414b88716.dirty\n\n\n"},{"id":"556049","messageId":"4f14a14a-99a9-4a01-bbab-ee1630e109f6@app.fastmail.com","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"Re: [PATCH v2 0/5] stash completion miscellany","fromName":"Kristoffer Haugsbakk","fromEmail":"kristofferhaugsbakk@fastmail.com","sentAt":"2026-10-23T14:33:22Z","receivedAt":"2026-10-23T14:33:22Z","isPatch":true,"sender":{"key":"kristofferhaugsbakk@fastmail.com","avatar":null},"body":"On Fri, Oct 23, 2026, at 15:20, D. Ben Knoble wrote:\n> This short patch series takes care of a few paper cuts in stash\n> completion. The first patch is a small code cleanup I noticed a while\n> back while working on bfc1b34859 (completion: add stash import, export,\n> 2026-02-07), I think. The next 2 take care of a problem I've been having\n> with Zsh's completion of stashes (cf. Unix & Linux SE [1]).\n>\n> [1]: https://unix.stackexchange.com/q/807580/301073\n>\n>[snip]\n>\n> Generated-with: git format-patch @{u}.. -o p -v2\n> --range-diff=@{u}..d1d0bf2d9a7d380d10771b5d1bceb8db91c5f05e\n> --in-reply-to=cover.1791827304.git.ben.knoble@gmail.com --cc='Patrick\n> Steinhardt <ps@pks.im>'\n>\n> I accidentally left the above line in v1, but I'm considering leaving it in from\n> now on?\n\n;)\n\n> It's the exact command I run to generate patches; I store it as a\n> \"trailer\" in the branch description, then run \"git generated-with\"† which\n> (effectively) does\n>\n>     eval \"$(git bdesc | git interpret-trailers --parse | grep\n> ^Generated-with | cut -d: -f 2-)\"\n>\n> where \"bdesc\" is an alias for\n>\n>     git -c core.editor=cat branch --edit-description | git stripspace -s\n>\n> Anyway, I've been hand-editing them out of cover letters for the last few\n> series, but if it doesn't bother anyone I'll just leave it around. Might be\n> helpful for new folks learning how to format patches?\n\nI think it’s a decent-to-good idea to leave it in.\n\n>\n> †:\n> https://github.com/benknoble/Dotfiles/blob/master/links/bin/git-generated-with\n>[snip]\n\n"},{"id":"556081","messageId":"xmqqpkx08hyk.fsf@gitster.g","threadId":"66507","inReplyTo":"0266646fb4e6eb4932ec728ce425af9886e5f146.1792761643.git.ben.knoble@gmail.com","subject":"Re: [PATCH v2 5/5] completion: drop \"stash save\" completion altogether","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-10-23T17:06:27Z","receivedAt":"2026-10-23T17:06:27Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n\n> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n> deprecated in the man page, 2017-10-22) and the previous commit removed\n> further documentation suggesting to use it.\n>\n> Since we recommend push instead, stop completing for \"save\" and remove a\n> special case in completion code. It still appears for \"git stash <tab>\"\n> when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still\n> complete options for\n>\n>     git stash save --<tab>\n>\n> which is helpful for folks with finger-memory for save.\n\nWell, if we can replace the command line to \"git stash push --\" on\nthe first <tab> and then start completing for \"stash push\" with the\nsecond <tab>, it would be superb.\n\n> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n> index 697fef5462..9cd9c7cadb 100644\n> --- a/contrib/completion/git-completion.bash\n> +++ b/contrib/completion/git-completion.bash\n> @@ -3558,16 +3558,13 @@ _git_stash ()\n>  \t__git_resolve_builtins stash\n>  \n>  \tsubcommands=\"$___git_resolved_builtins\"\n> -\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n> +\tsubcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>  \n>  \tif [ -z \"$subcommand\" ]; then\n>  \t\tcase \"$((cword - __git_cmd_idx)),$cur\" in\n>  \t\t*,--*)\n>  \t\t\t__gitcomp_builtin stash_push\n>  \t\t\t;;\n> -\t\t1,sa*)\n> -\t\t\t__gitcomp \"save\"\n> -\t\t\t;;\n\nNice to see this go.  This would have been maintenance nightmare if\nleft forever as we will have to remember updating it when \"sa\" no\nlonger becomes a unique prefix.\n\n"},{"id":"556082","messageId":"xmqqjyn88hyf.fsf@gitster.g","threadId":"66507","inReplyTo":"abf8efb792e6cc90db2752baaef4a7bb1d00f4b1.1792761643.git.ben.knoble@gmail.com","subject":"Re: [PATCH v2 2/5] Completion: extract common stash listing code","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-10-23T17:06:32Z","receivedAt":"2026-10-23T17:06:32Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"\"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n\n> With no change in behavior, prepare to adjust how stashes are completed\n> by centralizing candidate generation.\n>\n> Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>\n> ---\n>  contrib/completion/git-completion.bash | 11 +++++++----\n>  1 file changed, 7 insertions(+), 4 deletions(-)\n> @@ -3593,20 +3593,23 @@ _git_stash ()\n>  \t\tif [ $cword -eq $((__git_cmd_idx+2)) ]; then\n>  \t\t\t__git_complete_refs\n>  \t\telse\n> -\t\t\t__gitcomp_nl \"$(__git stash list \\\n> -\t\t\t\t\t| sed -n -e 's/:.*//p')\"\n> +\t\t\t__git_complete_stashes\n> ...\n> -\t\t__gitcomp_nl \"$(__git stash list \\\n> -\t\t\t\t| sed -n -e 's/:.*//p')\"\n> +\t\t__git_complete_stashes\n\nNice to see two of these unsightly constructs go ;-)\n\n"},{"id":"556091","messageId":"53FFC1C4-1569-4A9D-A1B7-B60A1BF53DF2@gmail.com","threadId":"66507","inReplyTo":"xmqqpkx08hyk.fsf@gitster.g","subject":"Re: [PATCH v2 5/5] completion: drop \"stash save\" completion altogether","fromName":"Ben Knoble","fromEmail":"ben.knoble@gmail.com","sentAt":"2026-10-23T18:07:36Z","receivedAt":"2026-10-23T18:07:36Z","isPatch":true,"sender":{"key":"ben.knoble@gmail.com","avatar":"https://avatars.githubusercontent.com/u/22802209?v=4"},"body":"\n> Le 23 oct. 2026 à 13:06, Junio C Hamano <gitster@pobox.com> a écrit :\n> \n> ﻿\"D. Ben Knoble\" <ben.knoble@gmail.com> writes:\n> \n>> It's been deprecated since fd2ebf14db (stash: mark \"git stash save\"\n>> deprecated in the man page, 2017-10-22) and the previous commit removed\n>> further documentation suggesting to use it.\n>> \n>> Since we recommend push instead, stop completing for \"save\" and remove a\n>> special case in completion code. It still appears for \"git stash <tab>\"\n>> when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still\n>> complete options for\n>> \n>>    git stash save --<tab>\n>> \n>> which is helpful for folks with finger-memory for save.\n> \n> Well, if we can replace the command line to \"git stash push --\" on\n> the first <tab> and then start completing for \"stash push\" with the\n> second <tab>, it would be superb.\n\nWe probably can (I know Zsh is capable), but that means\nmore complex special-casing ;) I’d rather get rid of this case\nand leave that nicety for someone who’s motivated to get\nconsensus for it, which I am not. \n\n> \n>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash\n>> index 697fef5462..9cd9c7cadb 100644\n>> --- a/contrib/completion/git-completion.bash\n>> +++ b/contrib/completion/git-completion.bash\n>> @@ -3558,16 +3558,13 @@ _git_stash ()\n>>    __git_resolve_builtins stash\n>> \n>>    subcommands=\"$___git_resolved_builtins\"\n>> -    subcommand=\"$(__git_find_on_cmdline \"$subcommands save\")\"\n>> +    subcommand=\"$(__git_find_on_cmdline \"$subcommands\")\"\n>> \n>>    if [ -z \"$subcommand\" ]; then\n>>        case \"$((cword - __git_cmd_idx)),$cur\" in\n>>        *,--*)\n>>            __gitcomp_builtin stash_push\n>>            ;;\n>> -        1,sa*)\n>> -            __gitcomp \"save\"\n>> -            ;;\n> \n> Nice to see this go.  This would have been maintenance nightmare if\n> left forever as we will have to remember updating it when \"sa\" no\n> longer becomes a unique prefix.\n\n"},{"id":"556284","messageId":"at8TywNz2WcDc-0c@pks.im","threadId":"66507","inReplyTo":"cover.1792761643.git.ben.knoble@gmail.com","subject":"Re: [PATCH v2 0/5] stash completion miscellany","fromName":"Patrick Steinhardt","fromEmail":"ps@pks.im","sentAt":"2026-10-26T08:48:11Z","receivedAt":"2026-10-26T08:48:11Z","isPatch":true,"sender":{"key":"ps@pks.im","avatar":"https://avatars.githubusercontent.com/u/4056630?v=4"},"body":"On Fri, Oct 23, 2026 at 09:20:50AM -0400, D. Ben Knoble wrote:\n> Diff-intervalle contre v1 :\n> 1:  d0e461a14a ! 1:  90d36b6445 completion: simplify stash subcommand completion\n>     @@ Commit message\n>          The stash completion helper contains a hard-coded list of commands, but\n>          git-stash provides a mechanism to list such commands\n>          (--git-completion-helper). The pattern for using it is wrapped by\n>     -    __git_resolve_builtins, so use it, bring _git_stash closer in line with\n>     -    other completion helpers.\n>     +    __git_resolve_builtins, so use it, bringing _git_stash closer in line\n>     +    with other completion helpers. As a nice side-benefit, this also adds\n>     +    \"store\" subcommand completion, which is missing from the explicit list\n>     +    of subcommands.\n\nYup.\n\n>     -    Note that we maintain the \"save\" special case, since it was removed from\n>     +    Note that we maintain the \"save\" special case†, since it was removed from\n>          default completion in 0eb5a4f911 (completion: stop showing 'save' for\n>     -    stash by default, 2018-04-20). We don't have to do anything special with\n>     -    the exclude (3rd) argument to __git_resolve_builtins, though, because\n>     -    save is already marked PARSE_OPT_NOCOMPLETE.\n>     +    stash by default, 2018-04-20). One might think we need to give \"save\" to\n>     +    __git_resolve_builtins' 3rd exclude argument to prevent it from\n>     +    showing up, but we don't: \"save\" is already marked PARSE_OPT_NOCOMPLETE.\n>     +\n>     +    †We don't complete the \"save\" subcommand unless at least \"sa\" has been\n>     +    typed, but we do complete its options if explicitly typed. With this\n>     +    change, we will complete \"save\" if GIT_COMPLETION_SHOW_ALL=1.\n\nGood.\n\n> 5:  d1d0bf2d9a ! 5:  0266646fb4 completion: drop \"stash save\" completion altogether\n>     @@ Commit message\n>          further documentation suggesting to use it.\n>      \n>          Since we recommend push instead, stop completing for \"save\" and remove a\n>     -    special case in completion code.\n>     +    special case in completion code. It still appears for \"git stash <tab>\"\n>     +    when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still\n>     +    complete options for\n>     +\n>     +        git stash save --<tab>\n>     +\n>     +    which is helpful for folks with finger-memory for save.\n\nAgreed, documenting the status quo feels reasonable to me.\n\nSo overall I'm happy with this v2, thanks!\n\nPatrick\n\n"},{"id":"556351","messageId":"xmqqtsm8v8jl.fsf@gitster.g","threadId":"66507","inReplyTo":"at8TywNz2WcDc-0c@pks.im","subject":"Re: [PATCH v2 0/5] stash completion miscellany","fromName":"Junio C Hamano","fromEmail":"gitster@pobox.com","sentAt":"2026-10-26T14:30:22Z","receivedAt":"2026-10-26T14:30:22Z","isPatch":true,"sender":{"key":"gitster@pobox.com","avatar":"https://avatars.githubusercontent.com/u/54884?v=4"},"body":"Patrick Steinhardt <ps@pks.im> writes:\n\n>>     -    special case in completion code.\n>>     +    special case in completion code. It still appears for \"git stash <tab>\"\n>>     +    when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still\n>>     +    complete options for\n>>     +\n>>     +        git stash save --<tab>\n>>     +\n>>     +    which is helpful for folks with finger-memory for save.\n>\n> Agreed, documenting the status quo feels reasonable to me.\n>\n> So overall I'm happy with this v2, thanks!\n\nThanks for writing and reviewing.\n\n"}]}