Git development
 help / color / mirror / Atom feed
* [PATCH] completion: exclude previous file arguments in Zsh
@ 2026-10-03 11:22 Fionn via GitGitGadget
  2026-10-04  8:07 ` SZEDER Gábor
  0 siblings, 1 reply; 5+ messages in thread
From: Fionn via GitGitGadget @ 2026-10-03 11:22 UTC (permalink / raw)
  To: git; +Cc: Felipe Contreras, Fionn, Fionn Fitzmaurice

From: Fionn Fitzmaurice <git@fionn.email>

When using the _git completion function bundled with Zsh
(https://sf.net/p/zsh/code/ci/master/tree/Completion/Unix/Command/_git),
duplicate files in an argument list will not be offered as completion
candidates.

For example, suppose we have untracked files aa and ab (only). Then with
the Zsh completion,

    git add aa a<tab>

would not offer both aa and ab as completion candidates, rather it would
complete ab only.

This behaviour is not present in git-completion.zsh shipped with Git,
which does not deduplicate arguments.

We can get this with minor changes, however. Here we introduce an array
__git_file_exclude which we populate with existing arguments and then
tell compadd to exclude them, which closely matches the Zsh _git
completion behaviour (as well as common programs such as rm).

Signed-off-by: Fionn Fitzmaurice <git@fionn.email>
---
    completion: exclude previous file arguments in Zsh

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-2216%2Ffionn%2Fzsh-completion-exclude-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-2216/fionn/zsh-completion-exclude-v1
Pull-Request: https://github.com/git/git/pull/2216

 contrib/completion/git-completion.zsh | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index d5c526665b..26444923c1 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -117,7 +117,7 @@ __gitcomp_file ()
 	emulate -L zsh
 
 	compset -P '*[=:]'
-	compadd -f -p "${2-}" -- ${(f)1} && _ret=0
+	compadd -f -p "${2-}" -F __git_file_exclude -- ${(f)1} && _ret=0
 }
 
 __gitcomp_direct_append ()
@@ -284,6 +284,8 @@ __git_zsh_main ()
 
 		(( $+opt_args[--help] )) && command='help'
 
+		__git_file_exclude=(${words[2,-1]:#${words[CURRENT]}})
+
 		words=( ${orig_words[@]} )
 
 		__git_zsh_bash_func $command
@@ -296,6 +298,7 @@ _git ()
 	local _ret=1
 	local cur cword prev
 	local __git_repo_path
+	local -a __git_file_exclude
 
 	cur=${words[CURRENT]}
 	prev=${words[CURRENT-1]}

base-commit: c46c1e37724f0478939de636ab8ea5a89086d532
-- 
gitgitgadget

^ permalink raw reply related	[flat|nested] 5+ messages in thread

* Re: [PATCH] completion: exclude previous file arguments in Zsh
  2026-10-03 11:22 [PATCH] completion: exclude previous file arguments in Zsh Fionn via GitGitGadget
@ 2026-10-04  8:07 ` SZEDER Gábor
  2026-10-04 16:17   ` Fionn
  2026-10-04 21:13   ` Junio C Hamano
  0 siblings, 2 replies; 5+ messages in thread
From: SZEDER Gábor @ 2026-10-04  8:07 UTC (permalink / raw)
  To: Fionn via GitGitGadget; +Cc: git, Felipe Contreras, Fionn

On Sat, Oct 03, 2026 at 11:22:06AM +0000, Fionn via GitGitGadget wrote:
> We can get this with minor changes, however. Here we introduce an array
> __git_file_exclude which we populate with existing arguments and then

"existing arguments" of what?

> tell compadd to exclude them, which closely matches the Zsh _git
> completion behaviour (as well as common programs such as rm).


> @@ -284,6 +284,8 @@ __git_zsh_main ()
>  
>  		(( $+opt_args[--help] )) && command='help'
>  
> +		__git_file_exclude=(${words[2,-1]:#${words[CURRENT]}})

I don't do Zsh, but that 2 as index looks suspicious.

What will be excluded in the following command line:

  git -C dir -C subdir -c foo.bar=baz add file1 file2 <TAB>

I think we should exclude only those arguments that come after the git
command, in this case after "add", i.e. "file1" and "file2", but I
suspect that everything starting with "dir" will get excluded.

> +
>  		words=( ${orig_words[@]} )
>  
>  		__git_zsh_bash_func $command

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] completion: exclude previous file arguments in Zsh
  2026-10-04  8:07 ` SZEDER Gábor
@ 2026-10-04 16:17   ` Fionn
  2026-10-04 21:13   ` Junio C Hamano
  1 sibling, 0 replies; 5+ messages in thread
From: Fionn @ 2026-10-04 16:17 UTC (permalink / raw)
  To: SZEDER Gábor, Fionn via GitGitGadget; +Cc: git, Felipe Contreras, Fionn

> "existing arguments" of what?

Of a subcommand that takes paths.

> I don't do Zsh, but that 2 as index looks suspicious.

Fair to be suspicious. word[1] is the subcommand (e.g. "add"), so we 
index from 2 on in order to skip it. This is independent of where the 
subcommand appears in the entire command line.

> What will be excluded in the following command line:
>
>   git -C dir -C subdir -c foo.bar=baz add file1 file2 <TAB>
>
> I think we should exclude only those arguments that come after the git
> command, in this case after "add", i.e. "file1" and "file2", but I
> suspect that everything starting with "dir" will get excluded.

In my testing this works correctly (i.e. file1 and file2 are not offered 
as completion candidates any more, but if e.g. dir or foo exist in the 
subdirectory, they would be offered).

I've been dogfooding this for about 8 months on and off. Occasionally 
completion candidates I'd hope would be excluded are present, but this 
is because the fallback completion bypasses __gitcomp_file, which is a 
separate issue. I have not yet encountered completion candidates being 
unexpectedly excluded.

An easy way to test this is to link git-completion.zsh to _git and then 
add

    fpath=(/path/to/directory/containing/_git/file $fpath[@])

to ~/.zshrc, or similar.

^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] completion: exclude previous file arguments in Zsh
  2026-10-04  8:07 ` SZEDER Gábor
  2026-10-04 16:17   ` Fionn
@ 2026-10-04 21:13   ` Junio C Hamano
  2026-10-05  1:44     ` Fionn
  1 sibling, 1 reply; 5+ messages in thread
From: Junio C Hamano @ 2026-10-04 21:13 UTC (permalink / raw)
  To: SZEDER Gábor; +Cc: Fionn via GitGitGadget, git, Felipe Contreras, Fionn

SZEDER Gábor <szeder.dev@gmail.com> writes:

> What will be excluded in the following command line:
>
>   git -C dir -C subdir -c foo.bar=baz add file1 file2 <TAB>
>
> I think we should exclude only those arguments that come after the git
> command, in this case after "add", i.e. "file1" and "file2", but I
> suspect that everything starting with "dir" will get excluded.

I was writing the same message when I saw yours.

If you had a file called 'add' in the working tree and then typed
"a<TAB>" to complete, is 'add' offered together with other files
whose name begins with 'a'?


^ permalink raw reply	[flat|nested] 5+ messages in thread

* Re: [PATCH] completion: exclude previous file arguments in Zsh
  2026-10-04 21:13   ` Junio C Hamano
@ 2026-10-05  1:44     ` Fionn
  0 siblings, 0 replies; 5+ messages in thread
From: Fionn @ 2026-10-05  1:44 UTC (permalink / raw)
  To: Junio C Hamano, SZEDER Gábor
  Cc: Fionn via GitGitGadget, git, Felipe Contreras, Fionn

> If you had a file called 'add' in the working tree and then typed
> "a<TAB>" to complete, is 'add' offered together with other files
> whose name begins with 'a'?

It is indeed.

^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2026-10-05  1:45 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-03 11:22 [PATCH] completion: exclude previous file arguments in Zsh Fionn via GitGitGadget
2026-10-04  8:07 ` SZEDER Gábor
2026-10-04 16:17   ` Fionn
2026-10-04 21:13   ` Junio C Hamano
2026-10-05  1:44     ` Fionn

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox