* [PATCH 0/5] stash completion miscellany
@ 2026-10-12 17:48 D. Ben Knoble
2026-10-12 17:48 ` [PATCH 1/5] completion: simplify stash subcommand completion D. Ben Knoble
` (5 more replies)
0 siblings, 6 replies; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-12 17:48 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble
Hi all,
This short patch series takes care of a few paper cuts in stash
completion. The first patch is a small code cleanup I noticed a while
back while working on bfc1b34859 (completion: add stash import, export,
2026-02-07), I think. The next 2 take care of a problem I've been having
with Zsh's completion of stashes (cf. Unix & Linux SE [1]).
[1]: https://unix.stackexchange.com/q/807580/301073
The final 2 are not only about completion; I noticed we were
special-casing save completion, did some digging, and was a bit confused
by the status of "git stash save". So, I figured while I was here I
would start a conversation about (a) restoring the git-stash(1) manual
to it's "no save" version and (b) ripping out the special case.
These last 2 may be controversial, and I'm not particularly attached to
them, so if they need to be dropped I won't really complain. OTOH,
what's the point of a deprecated subcommand we still advertise? ;)
Generated-with: git format-patch @{u}.. -o p
[1/5] completion: simplify stash subcommand completion
[2/5] completion: extract common stash listing code
[3/5] completion: fix Zsh handling of stash names
[4/5] doc: drop usage mentions of "git stash save"
[5/5] completion: drop "stash save" completion altogether
Documentation/git-stash.adoc | 2 --
builtin/stash.c | 1 -
contrib/completion/git-completion.bash | 22 +++++++++++++---------
contrib/completion/git-completion.zsh | 5 +++++
4 files changed, 18 insertions(+), 12 deletions(-)
base-commit: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd
--
2.56.0.184.g5a00b4a6e9.dirty
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH 1/5] completion: simplify stash subcommand completion
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
@ 2026-10-12 17:48 ` D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-12 17:48 ` [PATCH 2/5] completion: extract common stash listing code D. Ben Knoble
` (4 subsequent siblings)
5 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-12 17:48 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Junio C Hamano,
Ævar Arnfjörð Bjarmason
The stash completion helper contains a hard-coded list of commands, but
git-stash provides a mechanism to list such commands
(--git-completion-helper). The pattern for using it is wrapped by
__git_resolve_builtins, so use it, bring _git_stash closer in line with
other completion helpers.
Note that we maintain the "save" special case, since it was removed from
default completion in 0eb5a4f911 (completion: stop showing 'save' for
stash by default, 2018-04-20). We don't have to do anything special with
the exclude (3rd) argument to __git_resolve_builtins, though, because
save is already marked PARSE_OPT_NOCOMPLETE.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.bash | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index c3a49e2e22..d60e85479c 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3553,8 +3553,12 @@ _git_sparse_checkout ()
_git_stash ()
{
- local subcommands='push list show apply clear drop pop create branch import export'
- local subcommand="$(__git_find_on_cmdline "$subcommands save")"
+ local subcommands subcommand
+
+ __git_resolve_builtins stash
+
+ subcommands="$___git_resolved_builtins"
+ subcommand="$(__git_find_on_cmdline "$subcommands save")"
if [ -z "$subcommand" ]; then
case "$((cword - __git_cmd_idx)),$cur" in
--
2.56.0.184.g5a00b4a6e9.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 2/5] completion: extract common stash listing code
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
2026-10-12 17:48 ` [PATCH 1/5] completion: simplify stash subcommand completion D. Ben Knoble
@ 2026-10-12 17:48 ` D. Ben Knoble
2026-10-12 17:48 ` [PATCH 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
` (3 subsequent siblings)
5 siblings, 0 replies; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-12 17:48 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Ævar Arnfjörð Bjarmason,
Junio C Hamano
With no change in behavior, prepare to adjust how stashes are completed
by centralizing candidate generation.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.bash | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index d60e85479c..697fef5462 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3593,20 +3593,23 @@ _git_stash ()
if [ $cword -eq $((__git_cmd_idx+2)) ]; then
__git_complete_refs
else
- __gitcomp_nl "$(__git stash list \
- | sed -n -e 's/:.*//p')"
+ __git_complete_stashes
fi
;;
import,*)
__git_complete_refs
;;
show,*|apply,*|drop,*|pop,*|export,*)
- __gitcomp_nl "$(__git stash list \
- | sed -n -e 's/:.*//p')"
+ __git_complete_stashes
;;
esac
}
+__git_complete_stashes ()
+{
+ __gitcomp_nl "$(__git stash list | sed -n -e 's/:.*//p')"
+}
+
_git_submodule ()
{
__git_has_doubledash && return
--
2.56.0.184.g5a00b4a6e9.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 3/5] completion: fix Zsh handling of stash names
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
2026-10-12 17:48 ` [PATCH 1/5] completion: simplify stash subcommand completion D. Ben Knoble
2026-10-12 17:48 ` [PATCH 2/5] completion: extract common stash listing code D. Ben Knoble
@ 2026-10-12 17:48 ` D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-12 17:48 ` [PATCH 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
` (2 subsequent siblings)
5 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-12 17:48 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Junio C Hamano
When Git completes stashes for Zsh, it eventually invokes something like
this (via our redefinition of __gitcomp_nl):
compadd -Q -S " " -p "" -- 'stash@{0}' 'stash@{1}' && _ret=0
Because of -Q, the braces are unquoted, and Zsh will leave us at (for
example)
git stash show stash@{
cursor ^
From here, the list-choices widget (on Ctrl-D by default) will show
stash@{0} and stash@{1}, but the complete-word widget (Tab) will just
add another brace. Zsh things we're trying to do a brace expansion, I
think! Interestingly, using menu-complete (Ctrl-N) does cycle through
matches, since it's taking a slightly different completion path in Zsh.
We might try to fix this by passing surrounding single quotes (using the
-S/-p arguments of compadd, which we can do via __gitcomp_nl's other
parameters), and indeed Zsh will generate
git stash show 'stash@{
cursor ^
but completing here won't find anything, and I'm not totally sure why.
Instead, though, we can let Zsh quote metacharacters (removing -Q) and
everything "just works." It changes the output format a bit (users see
stash@\{0\}, for example), but I find this an improvement over not being
able to complete names at all. menu-complete is unchanged aside from the
extra backslashes.
So, override stash listing completion in Zsh with a working version.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.zsh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index d5c526665b..2aea7770d2 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -135,6 +135,11 @@ __gitcomp_file_direct ()
__gitcomp_file "$1" ""
}
+__git_complete_stashes ()
+{
+ compadd -S ' ' -- ${(f)"$(__git stash list | sed -n -e 's/:.*//p')"} && _ret=0
+}
+
_git_zsh ()
{
__gitcomp "v1.1"
--
2.56.0.184.g5a00b4a6e9.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 4/5] doc: drop usage mentions of "git stash save"
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
` (2 preceding siblings ...)
2026-10-12 17:48 ` [PATCH 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
@ 2026-10-12 17:48 ` D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-12 17:48 ` [PATCH 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
5 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-12 17:48 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Jean-Noël Avila, Junio C Hamano,
Ævar Arnfjörð Bjarmason, Quentin Bernet
Even though we previously deprecated it in fd2ebf14db (stash: mark "git
stash save" deprecated in the man page, 2017-10-22), the save subcommand
clings to life. For example, 951ec747d4 (doc txt & -h consistency: make
"stash" consistent, 2022-10-13) brought back "save" to the git-stash(1)
synopsis, and 41a28eb6c1 (stash: implement '--staged' option for 'push'
and 'save', 2021-10-18) gave it new options. But we really discourage
its use in modern Git, so let's drop mention of it from -h usage and the
synopsis.
It's still described in the manual, since some descriptions talk about
the "save" command. As we haven't gone ahead with a full deprecation and
removal, we can leave these pieces for folks whose fingers still type
"save" and need a reference for its behavior.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
Notes (benknoble/commits):
AFAICT there was no discussion of its deprecation when re-adding save to
the documentation, so I wonder if that was just an oversight.
Documentation/git-stash.adoc | 2 --
builtin/stash.c | 1 -
2 files changed, 3 deletions(-)
diff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc
index d6e8c4144c..6bf510702b 100644
--- a/Documentation/git-stash.adoc
+++ b/Documentation/git-stash.adoc
@@ -18,8 +18,6 @@ git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | -
[-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
[--pathspec-from-file=<file> [--pathspec-file-nul]]
[--] [<pathspec>...]
-git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
- [-u | --include-untracked] [-a | --all] [<message>]
git stash clear
git stash create [<message>]
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
diff --git a/builtin/stash.c b/builtin/stash.c
index 7a9843413b..94869c2429 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -75,7 +75,6 @@ static const char * const git_stash_usage[] = {
BUILTIN_STASH_APPLY_USAGE,
BUILTIN_STASH_BRANCH_USAGE,
BUILTIN_STASH_PUSH_USAGE,
- BUILTIN_STASH_SAVE_USAGE,
BUILTIN_STASH_CLEAR_USAGE,
BUILTIN_STASH_CREATE_USAGE,
BUILTIN_STASH_STORE_USAGE,
--
2.56.0.184.g5a00b4a6e9.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH 5/5] completion: drop "stash save" completion altogether
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
` (3 preceding siblings ...)
2026-10-12 17:48 ` [PATCH 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
@ 2026-10-12 17:48 ` D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
5 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-12 17:48 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Junio C Hamano, Rubén Justo,
Ævar Arnfjörð Bjarmason
It's been deprecated since fd2ebf14db (stash: mark "git stash save"
deprecated in the man page, 2017-10-22) and the previous commit removed
further documentation suggesting to use it.
Since we recommend push instead, stop completing for "save" and remove a
special case in completion code.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.bash | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 697fef5462..9cd9c7cadb 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3558,16 +3558,13 @@ _git_stash ()
__git_resolve_builtins stash
subcommands="$___git_resolved_builtins"
- subcommand="$(__git_find_on_cmdline "$subcommands save")"
+ subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
case "$((cword - __git_cmd_idx)),$cur" in
*,--*)
__gitcomp_builtin stash_push
;;
- 1,sa*)
- __gitcomp "save"
- ;;
1,*)
__gitcomp "$subcommands"
;;
--
2.56.0.184.g5a00b4a6e9.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH 3/5] completion: fix Zsh handling of stash names
2026-10-12 17:48 ` [PATCH 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
@ 2026-10-16 8:01 ` Patrick Steinhardt
2026-10-19 19:56 ` Ben Knoble
0 siblings, 1 reply; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-16 8:01 UTC (permalink / raw)
To: D. Ben Knoble; +Cc: git, Junio C Hamano
On Mon, Oct 12, 2026 at 01:48:29PM -0400, D. Ben Knoble wrote:
> When Git completes stashes for Zsh, it eventually invokes something like
> this (via our redefinition of __gitcomp_nl):
>
> compadd -Q -S " " -p "" -- 'stash@{0}' 'stash@{1}' && _ret=0
>
> Because of -Q, the braces are unquoted, and Zsh will leave us at (for
> example)
>
> git stash show stash@{
> cursor ^
>
> From here, the list-choices widget (on Ctrl-D by default) will show
> stash@{0} and stash@{1}, but the complete-word widget (Tab) will just
> add another brace. Zsh things we're trying to do a brace expansion, I
s/things/thinks/
> think! Interestingly, using menu-complete (Ctrl-N) does cycle through
> matches, since it's taking a slightly different completion path in Zsh.
>
> We might try to fix this by passing surrounding single quotes (using the
> -S/-p arguments of compadd, which we can do via __gitcomp_nl's other
> parameters), and indeed Zsh will generate
>
> git stash show 'stash@{
> cursor ^
>
> but completing here won't find anything, and I'm not totally sure why.
>
> Instead, though, we can let Zsh quote metacharacters (removing -Q) and
> everything "just works." It changes the output format a bit (users see
> stash@\{0\}, for example), but I find this an improvement over not being
> able to complete names at all. menu-complete is unchanged aside from the
> extra backslashes.
>
> So, override stash listing completion in Zsh with a working version.
Hm. I assume you tried finding a variant that works for both Bash and
Zsh so that we don't have to carry this override?
> diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
> index d5c526665b..2aea7770d2 100644
> --- a/contrib/completion/git-completion.zsh
> +++ b/contrib/completion/git-completion.zsh
> @@ -135,6 +135,11 @@ __gitcomp_file_direct ()
> __gitcomp_file "$1" ""
> }
>
> +__git_complete_stashes ()
> +{
> + compadd -S ' ' -- ${(f)"$(__git stash list | sed -n -e 's/:.*//p')"} && _ret=0
> +}
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 4/5] doc: drop usage mentions of "git stash save"
2026-10-12 17:48 ` [PATCH 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
@ 2026-10-16 8:01 ` Patrick Steinhardt
0 siblings, 0 replies; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-16 8:01 UTC (permalink / raw)
To: D. Ben Knoble
Cc: git, Jean-Noël Avila, Junio C Hamano,
Ævar Arnfjörð Bjarmason, Quentin Bernet
On Mon, Oct 12, 2026 at 01:48:30PM -0400, D. Ben Knoble wrote:
> Even though we previously deprecated it in fd2ebf14db (stash: mark "git
> stash save" deprecated in the man page, 2017-10-22), the save subcommand
> clings to life. For example, 951ec747d4 (doc txt & -h consistency: make
Heh :)
> "stash" consistent, 2022-10-13) brought back "save" to the git-stash(1)
> synopsis, and 41a28eb6c1 (stash: implement '--staged' option for 'push'
> and 'save', 2021-10-18) gave it new options. But we really discourage
> its use in modern Git, so let's drop mention of it from -h usage and the
> synopsis.
>
> It's still described in the manual, since some descriptions talk about
> the "save" command. As we haven't gone ahead with a full deprecation and
> removal, we can leave these pieces for folks whose fingers still type
> "save" and need a reference for its behavior.
I was wondering why we still have the command as part of our synopsis in
case it's deprecated, so good that you address this, too.
> Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
> ---
>
> Notes (benknoble/commits):
> AFAICT there was no discussion of its deprecation when re-adding save to
> the documentation, so I wonder if that was just an oversight.
I bet. In any case, I agree with removing it from our synopsis again.
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 1/5] completion: simplify stash subcommand completion
2026-10-12 17:48 ` [PATCH 1/5] completion: simplify stash subcommand completion D. Ben Knoble
@ 2026-10-16 8:01 ` Patrick Steinhardt
2026-10-19 19:58 ` Ben Knoble
0 siblings, 1 reply; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-16 8:01 UTC (permalink / raw)
To: D. Ben Knoble; +Cc: git, Junio C Hamano, Ævar Arnfjörð Bjarmason
On Mon, Oct 12, 2026 at 01:48:27PM -0400, D. Ben Knoble wrote:
> The stash completion helper contains a hard-coded list of commands, but
> git-stash provides a mechanism to list such commands
> (--git-completion-helper). The pattern for using it is wrapped by
> __git_resolve_builtins, so use it, bring _git_stash closer in line with
s/bring/bringing/?
> other completion helpers.
>
> Note that we maintain the "save" special case, since it was removed from
> default completion in 0eb5a4f911 (completion: stop showing 'save' for
> stash by default, 2018-04-20). We don't have to do anything special with
> the exclude (3rd) argument to __git_resolve_builtins, though, because
> save is already marked PARSE_OPT_NOCOMPLETE.
I didn't understand the last sentence without going into the code.
I assume what you want to say is that we don't have to explicitly
exclude it when completing the subcommand because it's already marked as
NOCOMPLETE. But we don't want to fully ignore it, either, because we
want to be able to complete that subcommand if the user explicitly wrote
it?
So basically: we're not completing it if the user writes "git stash
sa<TAB>", but we then know to complete its options if the user writes
"git stash save --<TAB>". Which I guess makes sense for a deprecated
subcommand.
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index c3a49e2e22..d60e85479c 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -3553,8 +3553,12 @@ _git_sparse_checkout ()
>
> _git_stash ()
> {
> - local subcommands='push list show apply clear drop pop create branch import export'
> - local subcommand="$(__git_find_on_cmdline "$subcommands save")"
> + local subcommands subcommand
> +
> + __git_resolve_builtins stash
> +
> + subcommands="$___git_resolved_builtins"
> + subcommand="$(__git_find_on_cmdline "$subcommands save")"
More plumbing, but less stuff that we need to keep up-to-date. This also
fixes that the "store" subcommand wasn't completed, which should
probably be pointed out in the commit message.
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 5/5] completion: drop "stash save" completion altogether
2026-10-12 17:48 ` [PATCH 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
@ 2026-10-16 8:01 ` Patrick Steinhardt
2026-10-19 20:01 ` Ben Knoble
0 siblings, 1 reply; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-16 8:01 UTC (permalink / raw)
To: D. Ben Knoble
Cc: git, Junio C Hamano, Rubén Justo,
Ævar Arnfjörð Bjarmason
On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:
> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
> deprecated in the man page, 2017-10-22) and the previous commit removed
> further documentation suggesting to use it.
>
> Since we recommend push instead, stop completing for "save" and remove a
> special case in completion code.
This is the only part I'm a bit torn on. I think it's reasonable to not
autocomplete the "save" command, but if the user manually types it,
should we really stop autocompleting its options altogether?
Maybe the answer is "yes". After all, as you mentioned in the preceding
commit, the command is deprecated since 2017 already! And after almost
10 years I think it's fair to start giving users more nudges into the
direction of using "push" instead.
One note though: the command _will_ be completed in the case where you
have GIT_COMPLETION_SHOW_ALL set.
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 3/5] completion: fix Zsh handling of stash names
2026-10-16 8:01 ` Patrick Steinhardt
@ 2026-10-19 19:56 ` Ben Knoble
0 siblings, 0 replies; 28+ messages in thread
From: Ben Knoble @ 2026-10-19 19:56 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: git, Junio C Hamano
> Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :
>
> On Mon, Oct 12, 2026 at 01:48:29PM -0400, D. Ben Knoble wrote:
>> When Git completes stashes for Zsh, it eventually invokes something like
>> this (via our redefinition of __gitcomp_nl):
>>
>> compadd -Q -S " " -p "" -- 'stash@{0}' 'stash@{1}' && _ret=0
>>
>> Because of -Q, the braces are unquoted, and Zsh will leave us at (for
>> example)
>>
>> git stash show stash@{
>> cursor ^
>>
>> From here, the list-choices widget (on Ctrl-D by default) will show
>> stash@{0} and stash@{1}, but the complete-word widget (Tab) will just
>> add another brace. Zsh things we're trying to do a brace expansion, I
>
> s/things/thinks/
Will fix!
>> think! Interestingly, using menu-complete (Ctrl-N) does cycle through
>> matches, since it's taking a slightly different completion path in Zsh.
>>
>> We might try to fix this by passing surrounding single quotes (using the
>> -S/-p arguments of compadd, which we can do via __gitcomp_nl's other
>> parameters), and indeed Zsh will generate
>>
>> git stash show 'stash@{
>> cursor ^
>>
>> but completing here won't find anything, and I'm not totally sure why.
>>
>> Instead, though, we can let Zsh quote metacharacters (removing -Q) and
>> everything "just works." It changes the output format a bit (users see
>> stash@\{0\}, for example), but I find this an improvement over not being
>> able to complete names at all. menu-complete is unchanged aside from the
>> extra backslashes.
>>
>> So, override stash listing completion in Zsh with a working version.
>
> Hm. I assume you tried finding a variant that works for both Bash and
> Zsh so that we don't have to carry this override?
Actually, no. I assumed Bash was working and haven’t tested it either way.
Presumably we’d have a report from someone if it were doing what Zsh does?
Many Zsh users, OTOH, use the Zsh-distributed completions,
which stackoverflow for me (and anyway I prefer ours).
I won’t have time to see if Bash is also Brien here, but this shouldn’t
change Bash’s behavior at least.
Oh, re-reading: yes, I looked for something that was compatible
with existing code. I mentioned one such attempt (single quotes).
No luck, though.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 1/5] completion: simplify stash subcommand completion
2026-10-16 8:01 ` Patrick Steinhardt
@ 2026-10-19 19:58 ` Ben Knoble
0 siblings, 0 replies; 28+ messages in thread
From: Ben Knoble @ 2026-10-19 19:58 UTC (permalink / raw)
To: Patrick Steinhardt
Cc: git, Junio C Hamano, Ævar Arnfjörð Bjarmason
> Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :
>
> On Mon, Oct 12, 2026 at 01:48:27PM -0400, D. Ben Knoble wrote:
>> The stash completion helper contains a hard-coded list of commands, but
>> git-stash provides a mechanism to list such commands
>> (--git-completion-helper). The pattern for using it is wrapped by
>> __git_resolve_builtins, so use it, bring _git_stash closer in line with
>
> s/bring/bringing/?
Will fix!
>> other completion helpers.
>>
>> Note that we maintain the "save" special case, since it was removed from
>> default completion in 0eb5a4f911 (completion: stop showing 'save' for
>> stash by default, 2018-04-20). We don't have to do anything special with
>> the exclude (3rd) argument to __git_resolve_builtins, though, because
>> save is already marked PARSE_OPT_NOCOMPLETE.
>
> I didn't understand the last sentence without going into the code.
>
> I assume what you want to say is that we don't have to explicitly
> exclude it when completing the subcommand because it's already marked as
> NOCOMPLETE. But we don't want to fully ignore it, either, because we
> want to be able to complete that subcommand if the user explicitly wrote
> it?
>
> So basically: we're not completing it if the user writes "git stash
> sa<TAB>", but we then know to complete its options if the user writes
> "git stash save --<TAB>". Which I guess makes sense for a deprecated
> subcommand.
Correct. I got a little too familiar with the completion guts
while working on this. I’ll try reworking it when I get back to v2.
>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
>> index c3a49e2e22..d60e85479c 100644
>> --- a/contrib/completion/git-completion.bash
>> +++ b/contrib/completion/git-completion.bash
>> @@ -3553,8 +3553,12 @@ _git_sparse_checkout ()
>>
>> _git_stash ()
>> {
>> - local subcommands='push list show apply clear drop pop create branch import export'
>> - local subcommand="$(__git_find_on_cmdline "$subcommands save")"
>> + local subcommands subcommand
>> +
>> + __git_resolve_builtins stash
>> +
>> + subcommands="$___git_resolved_builtins"
>> + subcommand="$(__git_find_on_cmdline "$subcommands save")"
>
> More plumbing, but less stuff that we need to keep up-to-date.
And more aligned with other helpers, yep.
> This also
> fixes that the "store" subcommand wasn't completed, which should
> probably be pointed out in the commit message.
I missed that, will add. Thanks!
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 5/5] completion: drop "stash save" completion altogether
2026-10-16 8:01 ` Patrick Steinhardt
@ 2026-10-19 20:01 ` Ben Knoble
2026-10-20 6:05 ` Patrick Steinhardt
0 siblings, 1 reply; 28+ messages in thread
From: Ben Knoble @ 2026-10-19 20:01 UTC (permalink / raw)
To: Patrick Steinhardt
Cc: git, Junio C Hamano, Rubén Justo,
Ævar Arnfjörð Bjarmason
> Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :
>
> On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:
>> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
>> deprecated in the man page, 2017-10-22) and the previous commit removed
>> further documentation suggesting to use it.
>>
>> Since we recommend push instead, stop completing for "save" and remove a
>> special case in completion code.
>
> This is the only part I'm a bit torn on. I think it's reasonable to not
> autocomplete the "save" command, but if the user manually types it,
> should we really stop autocompleting its options altogether?
>
> Maybe the answer is "yes". After all, as you mentioned in the preceding
> commit, the command is deprecated since 2017 already! And after almost
> 10 years I think it's fair to start giving users more nudges into the
> direction of using "push" instead.
>
> One note though: the command _will_ be completed in the case where you
> have GIT_COMPLETION_SHOW_ALL set
I should definitely mention SHOW_ALL; I’m not actually sure
what happens for « git stash save --<TAB> » with this patch,
so I’ll double-check. I actually wonder if it will complete options.
Would that satisfy you if so ?
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 5/5] completion: drop "stash save" completion altogether
2026-10-19 20:01 ` Ben Knoble
@ 2026-10-20 6:05 ` Patrick Steinhardt
2026-10-22 13:14 ` D. Ben Knoble
0 siblings, 1 reply; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-20 6:05 UTC (permalink / raw)
To: Ben Knoble
Cc: git, Junio C Hamano, Rubén Justo,
Ævar Arnfjörð Bjarmason
On Mon, Oct 19, 2026 at 04:01:15PM -0400, Ben Knoble wrote:
>
> > Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :
> >
> > On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:
> >> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
> >> deprecated in the man page, 2017-10-22) and the previous commit removed
> >> further documentation suggesting to use it.
> >>
> >> Since we recommend push instead, stop completing for "save" and remove a
> >> special case in completion code.
> >
> > This is the only part I'm a bit torn on. I think it's reasonable to not
> > autocomplete the "save" command, but if the user manually types it,
> > should we really stop autocompleting its options altogether?
> >
> > Maybe the answer is "yes". After all, as you mentioned in the preceding
> > commit, the command is deprecated since 2017 already! And after almost
> > 10 years I think it's fair to start giving users more nudges into the
> > direction of using "push" instead.
> >
> > One note though: the command _will_ be completed in the case where you
> > have GIT_COMPLETION_SHOW_ALL set
>
> I should definitely mention SHOW_ALL; I’m not actually sure
> what happens for « git stash save --<TAB> » with this patch,
> so I’ll double-check. I actually wonder if it will complete options.
>
> Would that satisfy you if so ?
Probably depends on the outcome of your tests, but ultimately I think
I'd be fine with either of the options. But if we stop autocompleting we
should definitely mention SHOW_ALL.
Thanks!
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 5/5] completion: drop "stash save" completion altogether
2026-10-20 6:05 ` Patrick Steinhardt
@ 2026-10-22 13:14 ` D. Ben Knoble
2026-10-23 6:21 ` Patrick Steinhardt
0 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-22 13:14 UTC (permalink / raw)
To: Patrick Steinhardt
Cc: git, Junio C Hamano, Rubén Justo,
Ævar Arnfjörð Bjarmason
On Tue, Oct 20, 2026 at 2:05 AM Patrick Steinhardt <ps@pks.im> wrote:
>
> On Mon, Oct 19, 2026 at 04:01:15PM -0400, Ben Knoble wrote:
> >
> > > Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :
> > >
> > > On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:
> > >> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
> > >> deprecated in the man page, 2017-10-22) and the previous commit removed
> > >> further documentation suggesting to use it.
> > >>
> > >> Since we recommend push instead, stop completing for "save" and remove a
> > >> special case in completion code.
> > >
> > > This is the only part I'm a bit torn on. I think it's reasonable to not
> > > autocomplete the "save" command, but if the user manually types it,
> > > should we really stop autocompleting its options altogether?
> > >
> > > Maybe the answer is "yes". After all, as you mentioned in the preceding
> > > commit, the command is deprecated since 2017 already! And after almost
> > > 10 years I think it's fair to start giving users more nudges into the
> > > direction of using "push" instead.
> > >
> > > One note though: the command _will_ be completed in the case where you
> > > have GIT_COMPLETION_SHOW_ALL set
> >
> > I should definitely mention SHOW_ALL; I’m not actually sure
> > what happens for « git stash save --<TAB> » with this patch,
> > so I’ll double-check. I actually wonder if it will complete options.
> >
> > Would that satisfy you if so ?
>
> Probably depends on the outcome of your tests, but ultimately I think
> I'd be fine with either of the options. But if we stop autocompleting we
> should definitely mention SHOW_ALL.
Here's what my testing showed (all Zsh):
- with SHOW_ALL, "git stash <tab>" lists "save" as an option; "git
stash save --<tab>" completes options
- without SHOW_ALL, "git stash <tab>" does not list "save"; "git stash
sa<tab>" does not complete "save"; "git stash save --<tab>" completes
options
I'll update the commit locally to reflect this. Thoughts?
--
D. Ben Knoble
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH 5/5] completion: drop "stash save" completion altogether
2026-10-22 13:14 ` D. Ben Knoble
@ 2026-10-23 6:21 ` Patrick Steinhardt
0 siblings, 0 replies; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-23 6:21 UTC (permalink / raw)
To: D. Ben Knoble
Cc: git, Junio C Hamano, Rubén Justo,
Ævar Arnfjörð Bjarmason
On Thu, Oct 22, 2026 at 09:14:52AM -0400, D. Ben Knoble wrote:
> On Tue, Oct 20, 2026 at 2:05 AM Patrick Steinhardt <ps@pks.im> wrote:
> >
> > On Mon, Oct 19, 2026 at 04:01:15PM -0400, Ben Knoble wrote:
> > >
> > > > Le 16 oct. 2026 à 04:01, Patrick Steinhardt <ps@pks.im> a écrit :
> > > >
> > > > On Mon, Oct 12, 2026 at 01:48:31PM -0400, D. Ben Knoble wrote:
> > > >> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
> > > >> deprecated in the man page, 2017-10-22) and the previous commit removed
> > > >> further documentation suggesting to use it.
> > > >>
> > > >> Since we recommend push instead, stop completing for "save" and remove a
> > > >> special case in completion code.
> > > >
> > > > This is the only part I'm a bit torn on. I think it's reasonable to not
> > > > autocomplete the "save" command, but if the user manually types it,
> > > > should we really stop autocompleting its options altogether?
> > > >
> > > > Maybe the answer is "yes". After all, as you mentioned in the preceding
> > > > commit, the command is deprecated since 2017 already! And after almost
> > > > 10 years I think it's fair to start giving users more nudges into the
> > > > direction of using "push" instead.
> > > >
> > > > One note though: the command _will_ be completed in the case where you
> > > > have GIT_COMPLETION_SHOW_ALL set
> > >
> > > I should definitely mention SHOW_ALL; I’m not actually sure
> > > what happens for « git stash save --<TAB> » with this patch,
> > > so I’ll double-check. I actually wonder if it will complete options.
> > >
> > > Would that satisfy you if so ?
> >
> > Probably depends on the outcome of your tests, but ultimately I think
> > I'd be fine with either of the options. But if we stop autocompleting we
> > should definitely mention SHOW_ALL.
>
> Here's what my testing showed (all Zsh):
>
> - with SHOW_ALL, "git stash <tab>" lists "save" as an option; "git
> stash save --<tab>" completes options
> - without SHOW_ALL, "git stash <tab>" does not list "save"; "git stash
> sa<tab>" does not complete "save"; "git stash save --<tab>" completes
> options
>
> I'll update the commit locally to reflect this. Thoughts?
We could of course add logic to explicitly stop completing options for
the deprecated subcommand. But I doubt it's worth it? So I think this is
good enough.
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 0/5] stash completion miscellany
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
` (4 preceding siblings ...)
2026-10-12 17:48 ` [PATCH 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
@ 2026-10-23 13:20 ` D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 1/5] completion: simplify stash subcommand completion D. Ben Knoble
` (6 more replies)
5 siblings, 7 replies; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-23 13:20 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Patrick Steinhardt
Hi all,
This short patch series takes care of a few paper cuts in stash
completion. The first patch is a small code cleanup I noticed a while
back while working on bfc1b34859 (completion: add stash import, export,
2026-02-07), I think. The next 2 take care of a problem I've been having
with Zsh's completion of stashes (cf. Unix & Linux SE [1]).
[1]: https://unix.stackexchange.com/q/807580/301073
Changes in v2:
• Reworded a few commit messages thanks to Patrick
• Clarify the behavior of the final patches with completion for "git
stash save" (also thanks to Patrick)
The final 2 are not only about completion; I noticed we were
special-casing save completion, did some digging, and was a bit confused
by the status of "git stash save". So, I figured while I was here I
would start a conversation about (a) restoring the git-stash(1) manual
to it's "no save" version and (b) ripping out the special case.
These last 2 may be controversial, and I'm not particularly attached to
them, so if they need to be dropped I won't really complain. OTOH,
what's the point of a deprecated subcommand we still advertise? ;)
Generated-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>'
I accidentally left the above line in v1, but I'm considering leaving it in from
now on? It's the exact command I run to generate patches; I store it as a
"trailer" in the branch description, then run "git generated-with"† which
(effectively) does
eval "$(git bdesc | git interpret-trailers --parse | grep ^Generated-with | cut -d: -f 2-)"
where "bdesc" is an alias for
git -c core.editor=cat branch --edit-description | git stripspace -s
Anyway, I've been hand-editing them out of cover letters for the last few
series, but if it doesn't bother anyone I'll just leave it around. Might be
helpful for new folks learning how to format patches?
†: https://github.com/benknoble/Dotfiles/blob/master/links/bin/git-generated-with
[1/5] completion: simplify stash subcommand completion
[2/5] Completion: extract common stash listing code
[3/5] completion: fix Zsh handling of stash names
[4/5] doc: drop usage mentions of "git stash save"
[5/5] completion: drop "stash save" completion altogether
Documentation/git-stash.adoc | 2 --
builtin/stash.c | 1 -
contrib/completion/git-completion.bash | 22 +++++++++++++---------
contrib/completion/git-completion.zsh | 5 +++++
4 files changed, 18 insertions(+), 12 deletions(-)
Diff-intervalle contre v1 :
1: d0e461a14a ! 1: 90d36b6445 completion: simplify stash subcommand completion
@@ Commit message
The stash completion helper contains a hard-coded list of commands, but
git-stash provides a mechanism to list such commands
(--git-completion-helper). The pattern for using it is wrapped by
- __git_resolve_builtins, so use it, bring _git_stash closer in line with
- other completion helpers.
+ __git_resolve_builtins, so use it, bringing _git_stash closer in line
+ with other completion helpers. As a nice side-benefit, this also adds
+ "store" subcommand completion, which is missing from the explicit list
+ of subcommands.
- Note that we maintain the "save" special case, since it was removed from
+ Note that we maintain the "save" special case†, since it was removed from
default completion in 0eb5a4f911 (completion: stop showing 'save' for
- stash by default, 2018-04-20). We don't have to do anything special with
- the exclude (3rd) argument to __git_resolve_builtins, though, because
- save is already marked PARSE_OPT_NOCOMPLETE.
+ stash by default, 2018-04-20). One might think we need to give "save" to
+ __git_resolve_builtins' 3rd exclude argument to prevent it from
+ showing up, but we don't: "save" is already marked PARSE_OPT_NOCOMPLETE.
+
+ †We don't complete the "save" subcommand unless at least "sa" has been
+ typed, but we do complete its options if explicitly typed. With this
+ change, we will complete "save" if GIT_COMPLETION_SHOW_ALL=1.
## contrib/completion/git-completion.bash ##
@@ contrib/completion/git-completion.bash: _git_sparse_checkout ()
2: 6c24a833fc = 2: abf8efb792 Completion: extract common stash listing code
3: 22283a1d5f ! 3: f4f6b89ff6 completion: fix Zsh handling of stash names
@@ Commit message
From here, the list-choices widget (on Ctrl-D by default) will show
stash@{0} and stash@{1}, but the complete-word widget (Tab) will just
- add another brace. Zsh things we're trying to do a brace expansion, I
+ add another brace. Zsh thinks we're trying to do a brace expansion, I
think! Interestingly, using menu-complete (Ctrl-N) does cycle through
matches, since it's taking a slightly different completion path in Zsh.
We might try to fix this by passing surrounding single quotes (using the
- -S/-p arguments of compadd, which we can do via __gitcomp_nl's other
- parameters), and indeed Zsh will generate
+ -S/-p arguments of compadd, which we can do from Bash in our code via
+ __gitcomp_nl's other parameters), and indeed Zsh will generate
git stash show 'stash@{
cursor ^
4: 985a14f18e = 4: 3762f9d5bb doc: drop usage mentions of "git stash save"
5: d1d0bf2d9a ! 5: 0266646fb4 completion: drop "stash save" completion altogether
@@ Commit message
further documentation suggesting to use it.
Since we recommend push instead, stop completing for "save" and remove a
- special case in completion code.
+ special case in completion code. It still appears for "git stash <tab>"
+ when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still
+ complete options for
+
+ git stash save --<tab>
+
+ which is helpful for folks with finger-memory for save.
## contrib/completion/git-completion.bash ##
@@ contrib/completion/git-completion.bash: _git_stash ()
base-commit: 6de20f6092dcf9bdb1c8efe03db4b70c82b423dd
--
2.56.0.237.g5414b88716.dirty
^ permalink raw reply [flat|nested] 28+ messages in thread
* [PATCH v2 1/5] completion: simplify stash subcommand completion
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
@ 2026-10-23 13:20 ` D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 2/5] Completion: extract common stash listing code D. Ben Knoble
` (5 subsequent siblings)
6 siblings, 0 replies; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-23 13:20 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Patrick Steinhardt, Junio C Hamano
The stash completion helper contains a hard-coded list of commands, but
git-stash provides a mechanism to list such commands
(--git-completion-helper). The pattern for using it is wrapped by
__git_resolve_builtins, so use it, bringing _git_stash closer in line
with other completion helpers. As a nice side-benefit, this also adds
"store" subcommand completion, which is missing from the explicit list
of subcommands.
Note that we maintain the "save" special case†, since it was removed from
default completion in 0eb5a4f911 (completion: stop showing 'save' for
stash by default, 2018-04-20). One might think we need to give "save" to
__git_resolve_builtins' 3rd exclude argument to prevent it from
showing up, but we don't: "save" is already marked PARSE_OPT_NOCOMPLETE.
†We don't complete the "save" subcommand unless at least "sa" has been
typed, but we do complete its options if explicitly typed. With this
change, we will complete "save" if GIT_COMPLETION_SHOW_ALL=1.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.bash | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index c3a49e2e22..d60e85479c 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3553,8 +3553,12 @@ _git_sparse_checkout ()
_git_stash ()
{
- local subcommands='push list show apply clear drop pop create branch import export'
- local subcommand="$(__git_find_on_cmdline "$subcommands save")"
+ local subcommands subcommand
+
+ __git_resolve_builtins stash
+
+ subcommands="$___git_resolved_builtins"
+ subcommand="$(__git_find_on_cmdline "$subcommands save")"
if [ -z "$subcommand" ]; then
case "$((cword - __git_cmd_idx)),$cur" in
--
2.56.0.237.g5414b88716.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 2/5] Completion: extract common stash listing code
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 1/5] completion: simplify stash subcommand completion D. Ben Knoble
@ 2026-10-23 13:20 ` D. Ben Knoble
2026-10-23 17:06 ` Junio C Hamano
2026-10-23 13:20 ` [PATCH v2 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
` (4 subsequent siblings)
6 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-23 13:20 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Patrick Steinhardt, Junio C Hamano
With no change in behavior, prepare to adjust how stashes are completed
by centralizing candidate generation.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.bash | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index d60e85479c..697fef5462 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3593,20 +3593,23 @@ _git_stash ()
if [ $cword -eq $((__git_cmd_idx+2)) ]; then
__git_complete_refs
else
- __gitcomp_nl "$(__git stash list \
- | sed -n -e 's/:.*//p')"
+ __git_complete_stashes
fi
;;
import,*)
__git_complete_refs
;;
show,*|apply,*|drop,*|pop,*|export,*)
- __gitcomp_nl "$(__git stash list \
- | sed -n -e 's/:.*//p')"
+ __git_complete_stashes
;;
esac
}
+__git_complete_stashes ()
+{
+ __gitcomp_nl "$(__git stash list | sed -n -e 's/:.*//p')"
+}
+
_git_submodule ()
{
__git_has_doubledash && return
--
2.56.0.237.g5414b88716.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 3/5] completion: fix Zsh handling of stash names
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 1/5] completion: simplify stash subcommand completion D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 2/5] Completion: extract common stash listing code D. Ben Knoble
@ 2026-10-23 13:20 ` D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
` (3 subsequent siblings)
6 siblings, 0 replies; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-23 13:20 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Patrick Steinhardt, Junio C Hamano
When Git completes stashes for Zsh, it eventually invokes something like
this (via our redefinition of __gitcomp_nl):
compadd -Q -S " " -p "" -- 'stash@{0}' 'stash@{1}' && _ret=0
Because of -Q, the braces are unquoted, and Zsh will leave us at (for
example)
git stash show stash@{
cursor ^
From here, the list-choices widget (on Ctrl-D by default) will show
stash@{0} and stash@{1}, but the complete-word widget (Tab) will just
add another brace. Zsh thinks we're trying to do a brace expansion, I
think! Interestingly, using menu-complete (Ctrl-N) does cycle through
matches, since it's taking a slightly different completion path in Zsh.
We might try to fix this by passing surrounding single quotes (using the
-S/-p arguments of compadd, which we can do from Bash in our code via
__gitcomp_nl's other parameters), and indeed Zsh will generate
git stash show 'stash@{
cursor ^
but completing here won't find anything, and I'm not totally sure why.
Instead, though, we can let Zsh quote metacharacters (removing -Q) and
everything "just works." It changes the output format a bit (users see
stash@\{0\}, for example), but I find this an improvement over not being
able to complete names at all. menu-complete is unchanged aside from the
extra backslashes.
So, override stash listing completion in Zsh with a working version.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.zsh | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index d5c526665b..2aea7770d2 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -135,6 +135,11 @@ __gitcomp_file_direct ()
__gitcomp_file "$1" ""
}
+__git_complete_stashes ()
+{
+ compadd -S ' ' -- ${(f)"$(__git stash list | sed -n -e 's/:.*//p')"} && _ret=0
+}
+
_git_zsh ()
{
__gitcomp "v1.1"
--
2.56.0.237.g5414b88716.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 4/5] doc: drop usage mentions of "git stash save"
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
` (2 preceding siblings ...)
2026-10-23 13:20 ` [PATCH v2 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
@ 2026-10-23 13:20 ` D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
` (2 subsequent siblings)
6 siblings, 0 replies; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-23 13:20 UTC (permalink / raw)
To: git
Cc: D. Ben Knoble, Patrick Steinhardt, Quentin Bernet, Junio C Hamano,
Ævar Arnfjörð Bjarmason, Sergey Organov,
Jean-Noël Avila
Even though we previously deprecated it in fd2ebf14db (stash: mark "git
stash save" deprecated in the man page, 2017-10-22), the save subcommand
clings to life. For example, 951ec747d4 (doc txt & -h consistency: make
"stash" consistent, 2022-10-13) brought back "save" to the git-stash(1)
synopsis, and 41a28eb6c1 (stash: implement '--staged' option for 'push'
and 'save', 2021-10-18) gave it new options. But we really discourage
its use in modern Git, so let's drop mention of it from -h usage and the
synopsis.
It's still described in the manual, since some descriptions talk about
the "save" command. As we haven't gone ahead with a full deprecation and
removal, we can leave these pieces for folks whose fingers still type
"save" and need a reference for its behavior.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
Documentation/git-stash.adoc | 2 --
builtin/stash.c | 1 -
2 files changed, 3 deletions(-)
diff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc
index d6e8c4144c..6bf510702b 100644
--- a/Documentation/git-stash.adoc
+++ b/Documentation/git-stash.adoc
@@ -18,8 +18,6 @@ git stash [push] [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | -
[-u | --include-untracked] [-a | --all] [(-m | --message) <message>]
[--pathspec-from-file=<file> [--pathspec-file-nul]]
[--] [<pathspec>...]
-git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | --quiet]
- [-u | --include-untracked] [-a | --all] [<message>]
git stash clear
git stash create [<message>]
git stash store [(-m | --message) <message>] [-q | --quiet] <commit>
diff --git a/builtin/stash.c b/builtin/stash.c
index 7a9843413b..94869c2429 100644
--- a/builtin/stash.c
+++ b/builtin/stash.c
@@ -75,7 +75,6 @@ static const char * const git_stash_usage[] = {
BUILTIN_STASH_APPLY_USAGE,
BUILTIN_STASH_BRANCH_USAGE,
BUILTIN_STASH_PUSH_USAGE,
- BUILTIN_STASH_SAVE_USAGE,
BUILTIN_STASH_CLEAR_USAGE,
BUILTIN_STASH_CREATE_USAGE,
BUILTIN_STASH_STORE_USAGE,
--
2.56.0.237.g5414b88716.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* [PATCH v2 5/5] completion: drop "stash save" completion altogether
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
` (3 preceding siblings ...)
2026-10-23 13:20 ` [PATCH v2 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
@ 2026-10-23 13:20 ` D. Ben Knoble
2026-10-23 17:06 ` Junio C Hamano
2026-10-23 14:33 ` [PATCH v2 0/5] stash completion miscellany Kristoffer Haugsbakk
2026-10-26 8:48 ` Patrick Steinhardt
6 siblings, 1 reply; 28+ messages in thread
From: D. Ben Knoble @ 2026-10-23 13:20 UTC (permalink / raw)
To: git; +Cc: D. Ben Knoble, Patrick Steinhardt, Junio C Hamano,
Rubén Justo
It's been deprecated since fd2ebf14db (stash: mark "git stash save"
deprecated in the man page, 2017-10-22) and the previous commit removed
further documentation suggesting to use it.
Since we recommend push instead, stop completing for "save" and remove a
special case in completion code. It still appears for "git stash <tab>"
when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still
complete options for
git stash save --<tab>
which is helpful for folks with finger-memory for save.
Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
---
contrib/completion/git-completion.bash | 5 +----
1 file changed, 1 insertion(+), 4 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 697fef5462..9cd9c7cadb 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -3558,16 +3558,13 @@ _git_stash ()
__git_resolve_builtins stash
subcommands="$___git_resolved_builtins"
- subcommand="$(__git_find_on_cmdline "$subcommands save")"
+ subcommand="$(__git_find_on_cmdline "$subcommands")"
if [ -z "$subcommand" ]; then
case "$((cword - __git_cmd_idx)),$cur" in
*,--*)
__gitcomp_builtin stash_push
;;
- 1,sa*)
- __gitcomp "save"
- ;;
1,*)
__gitcomp "$subcommands"
;;
--
2.56.0.237.g5414b88716.dirty
^ permalink raw reply related [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/5] stash completion miscellany
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
` (4 preceding siblings ...)
2026-10-23 13:20 ` [PATCH v2 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
@ 2026-10-23 14:33 ` Kristoffer Haugsbakk
2026-10-26 8:48 ` Patrick Steinhardt
6 siblings, 0 replies; 28+ messages in thread
From: Kristoffer Haugsbakk @ 2026-10-23 14:33 UTC (permalink / raw)
To: D. Ben Knoble, git; +Cc: Patrick Steinhardt
On Fri, Oct 23, 2026, at 15:20, D. Ben Knoble wrote:
> This short patch series takes care of a few paper cuts in stash
> completion. The first patch is a small code cleanup I noticed a while
> back while working on bfc1b34859 (completion: add stash import, export,
> 2026-02-07), I think. The next 2 take care of a problem I've been having
> with Zsh's completion of stashes (cf. Unix & Linux SE [1]).
>
> [1]: https://unix.stackexchange.com/q/807580/301073
>
>[snip]
>
> Generated-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>'
>
> I accidentally left the above line in v1, but I'm considering leaving it in from
> now on?
;)
> It's the exact command I run to generate patches; I store it as a
> "trailer" in the branch description, then run "git generated-with"† which
> (effectively) does
>
> eval "$(git bdesc | git interpret-trailers --parse | grep
> ^Generated-with | cut -d: -f 2-)"
>
> where "bdesc" is an alias for
>
> git -c core.editor=cat branch --edit-description | git stripspace -s
>
> Anyway, I've been hand-editing them out of cover letters for the last few
> series, but if it doesn't bother anyone I'll just leave it around. Might be
> helpful for new folks learning how to format patches?
I think it’s a decent-to-good idea to leave it in.
>
> †:
> https://github.com/benknoble/Dotfiles/blob/master/links/bin/git-generated-with
>[snip]
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 5/5] completion: drop "stash save" completion altogether
2026-10-23 13:20 ` [PATCH v2 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
@ 2026-10-23 17:06 ` Junio C Hamano
2026-10-23 18:07 ` Ben Knoble
0 siblings, 1 reply; 28+ messages in thread
From: Junio C Hamano @ 2026-10-23 17:06 UTC (permalink / raw)
To: D. Ben Knoble; +Cc: git, Patrick Steinhardt, Rubén Justo
"D. Ben Knoble" <ben.knoble@gmail.com> writes:
> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
> deprecated in the man page, 2017-10-22) and the previous commit removed
> further documentation suggesting to use it.
>
> Since we recommend push instead, stop completing for "save" and remove a
> special case in completion code. It still appears for "git stash <tab>"
> when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still
> complete options for
>
> git stash save --<tab>
>
> which is helpful for folks with finger-memory for save.
Well, if we can replace the command line to "git stash push --" on
the first <tab> and then start completing for "stash push" with the
second <tab>, it would be superb.
> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
> index 697fef5462..9cd9c7cadb 100644
> --- a/contrib/completion/git-completion.bash
> +++ b/contrib/completion/git-completion.bash
> @@ -3558,16 +3558,13 @@ _git_stash ()
> __git_resolve_builtins stash
>
> subcommands="$___git_resolved_builtins"
> - subcommand="$(__git_find_on_cmdline "$subcommands save")"
> + subcommand="$(__git_find_on_cmdline "$subcommands")"
>
> if [ -z "$subcommand" ]; then
> case "$((cword - __git_cmd_idx)),$cur" in
> *,--*)
> __gitcomp_builtin stash_push
> ;;
> - 1,sa*)
> - __gitcomp "save"
> - ;;
Nice to see this go. This would have been maintenance nightmare if
left forever as we will have to remember updating it when "sa" no
longer becomes a unique prefix.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 2/5] Completion: extract common stash listing code
2026-10-23 13:20 ` [PATCH v2 2/5] Completion: extract common stash listing code D. Ben Knoble
@ 2026-10-23 17:06 ` Junio C Hamano
0 siblings, 0 replies; 28+ messages in thread
From: Junio C Hamano @ 2026-10-23 17:06 UTC (permalink / raw)
To: D. Ben Knoble; +Cc: git, Patrick Steinhardt
"D. Ben Knoble" <ben.knoble@gmail.com> writes:
> With no change in behavior, prepare to adjust how stashes are completed
> by centralizing candidate generation.
>
> Signed-off-by: D. Ben Knoble <ben.knoble@gmail.com>
> ---
> contrib/completion/git-completion.bash | 11 +++++++----
> 1 file changed, 7 insertions(+), 4 deletions(-)
> @@ -3593,20 +3593,23 @@ _git_stash ()
> if [ $cword -eq $((__git_cmd_idx+2)) ]; then
> __git_complete_refs
> else
> - __gitcomp_nl "$(__git stash list \
> - | sed -n -e 's/:.*//p')"
> + __git_complete_stashes
> ...
> - __gitcomp_nl "$(__git stash list \
> - | sed -n -e 's/:.*//p')"
> + __git_complete_stashes
Nice to see two of these unsightly constructs go ;-)
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 5/5] completion: drop "stash save" completion altogether
2026-10-23 17:06 ` Junio C Hamano
@ 2026-10-23 18:07 ` Ben Knoble
0 siblings, 0 replies; 28+ messages in thread
From: Ben Knoble @ 2026-10-23 18:07 UTC (permalink / raw)
To: Junio C Hamano; +Cc: git, Patrick Steinhardt, Rubén Justo
> Le 23 oct. 2026 à 13:06, Junio C Hamano <gitster@pobox.com> a écrit :
>
> "D. Ben Knoble" <ben.knoble@gmail.com> writes:
>
>> It's been deprecated since fd2ebf14db (stash: mark "git stash save"
>> deprecated in the man page, 2017-10-22) and the previous commit removed
>> further documentation suggesting to use it.
>>
>> Since we recommend push instead, stop completing for "save" and remove a
>> special case in completion code. It still appears for "git stash <tab>"
>> when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still
>> complete options for
>>
>> git stash save --<tab>
>>
>> which is helpful for folks with finger-memory for save.
>
> Well, if we can replace the command line to "git stash push --" on
> the first <tab> and then start completing for "stash push" with the
> second <tab>, it would be superb.
We probably can (I know Zsh is capable), but that means
more complex special-casing ;) I’d rather get rid of this case
and leave that nicety for someone who’s motivated to get
consensus for it, which I am not.
>
>> diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
>> index 697fef5462..9cd9c7cadb 100644
>> --- a/contrib/completion/git-completion.bash
>> +++ b/contrib/completion/git-completion.bash
>> @@ -3558,16 +3558,13 @@ _git_stash ()
>> __git_resolve_builtins stash
>>
>> subcommands="$___git_resolved_builtins"
>> - subcommand="$(__git_find_on_cmdline "$subcommands save")"
>> + subcommand="$(__git_find_on_cmdline "$subcommands")"
>>
>> if [ -z "$subcommand" ]; then
>> case "$((cword - __git_cmd_idx)),$cur" in
>> *,--*)
>> __gitcomp_builtin stash_push
>> ;;
>> - 1,sa*)
>> - __gitcomp "save"
>> - ;;
>
> Nice to see this go. This would have been maintenance nightmare if
> left forever as we will have to remember updating it when "sa" no
> longer becomes a unique prefix.
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/5] stash completion miscellany
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
` (5 preceding siblings ...)
2026-10-23 14:33 ` [PATCH v2 0/5] stash completion miscellany Kristoffer Haugsbakk
@ 2026-10-26 8:48 ` Patrick Steinhardt
2026-10-26 14:30 ` Junio C Hamano
6 siblings, 1 reply; 28+ messages in thread
From: Patrick Steinhardt @ 2026-10-26 8:48 UTC (permalink / raw)
To: D. Ben Knoble; +Cc: git
On Fri, Oct 23, 2026 at 09:20:50AM -0400, D. Ben Knoble wrote:
> Diff-intervalle contre v1 :
> 1: d0e461a14a ! 1: 90d36b6445 completion: simplify stash subcommand completion
> @@ Commit message
> The stash completion helper contains a hard-coded list of commands, but
> git-stash provides a mechanism to list such commands
> (--git-completion-helper). The pattern for using it is wrapped by
> - __git_resolve_builtins, so use it, bring _git_stash closer in line with
> - other completion helpers.
> + __git_resolve_builtins, so use it, bringing _git_stash closer in line
> + with other completion helpers. As a nice side-benefit, this also adds
> + "store" subcommand completion, which is missing from the explicit list
> + of subcommands.
Yup.
> - Note that we maintain the "save" special case, since it was removed from
> + Note that we maintain the "save" special case†, since it was removed from
> default completion in 0eb5a4f911 (completion: stop showing 'save' for
> - stash by default, 2018-04-20). We don't have to do anything special with
> - the exclude (3rd) argument to __git_resolve_builtins, though, because
> - save is already marked PARSE_OPT_NOCOMPLETE.
> + stash by default, 2018-04-20). One might think we need to give "save" to
> + __git_resolve_builtins' 3rd exclude argument to prevent it from
> + showing up, but we don't: "save" is already marked PARSE_OPT_NOCOMPLETE.
> +
> + †We don't complete the "save" subcommand unless at least "sa" has been
> + typed, but we do complete its options if explicitly typed. With this
> + change, we will complete "save" if GIT_COMPLETION_SHOW_ALL=1.
Good.
> 5: d1d0bf2d9a ! 5: 0266646fb4 completion: drop "stash save" completion altogether
> @@ Commit message
> further documentation suggesting to use it.
>
> Since we recommend push instead, stop completing for "save" and remove a
> - special case in completion code.
> + special case in completion code. It still appears for "git stash <tab>"
> + when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still
> + complete options for
> +
> + git stash save --<tab>
> +
> + which is helpful for folks with finger-memory for save.
Agreed, documenting the status quo feels reasonable to me.
So overall I'm happy with this v2, thanks!
Patrick
^ permalink raw reply [flat|nested] 28+ messages in thread
* Re: [PATCH v2 0/5] stash completion miscellany
2026-10-26 8:48 ` Patrick Steinhardt
@ 2026-10-26 14:30 ` Junio C Hamano
0 siblings, 0 replies; 28+ messages in thread
From: Junio C Hamano @ 2026-10-26 14:30 UTC (permalink / raw)
To: Patrick Steinhardt; +Cc: D. Ben Knoble, git
Patrick Steinhardt <ps@pks.im> writes:
>> - special case in completion code.
>> + special case in completion code. It still appears for "git stash <tab>"
>> + when GIT_COMPLETION_SHOW_ALL=1, and when typed explicitly we still
>> + complete options for
>> +
>> + git stash save --<tab>
>> +
>> + which is helpful for folks with finger-memory for save.
>
> Agreed, documenting the status quo feels reasonable to me.
>
> So overall I'm happy with this v2, thanks!
Thanks for writing and reviewing.
^ permalink raw reply [flat|nested] 28+ messages in thread
end of thread, other threads:[~2026-10-26 14:30 UTC | newest]
Thread overview: 28+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-12 17:48 [PATCH 0/5] stash completion miscellany D. Ben Knoble
2026-10-12 17:48 ` [PATCH 1/5] completion: simplify stash subcommand completion D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-19 19:58 ` Ben Knoble
2026-10-12 17:48 ` [PATCH 2/5] completion: extract common stash listing code D. Ben Knoble
2026-10-12 17:48 ` [PATCH 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-19 19:56 ` Ben Knoble
2026-10-12 17:48 ` [PATCH 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-12 17:48 ` [PATCH 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
2026-10-16 8:01 ` Patrick Steinhardt
2026-10-19 20:01 ` Ben Knoble
2026-10-20 6:05 ` Patrick Steinhardt
2026-10-22 13:14 ` D. Ben Knoble
2026-10-23 6:21 ` Patrick Steinhardt
2026-10-23 13:20 ` [PATCH v2 0/5] stash completion miscellany D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 1/5] completion: simplify stash subcommand completion D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 2/5] Completion: extract common stash listing code D. Ben Knoble
2026-10-23 17:06 ` Junio C Hamano
2026-10-23 13:20 ` [PATCH v2 3/5] completion: fix Zsh handling of stash names D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 4/5] doc: drop usage mentions of "git stash save" D. Ben Knoble
2026-10-23 13:20 ` [PATCH v2 5/5] completion: drop "stash save" completion altogether D. Ben Knoble
2026-10-23 17:06 ` Junio C Hamano
2026-10-23 18:07 ` Ben Knoble
2026-10-23 14:33 ` [PATCH v2 0/5] stash completion miscellany Kristoffer Haugsbakk
2026-10-26 8:48 ` Patrick Steinhardt
2026-10-26 14:30 ` Junio C Hamano
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox