All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] completion: zsh: support completion after "git -C <path>"
@ 2026-06-17 15:30 Lutz Lengemann via GitGitGadget
  2026-06-17 17:17 ` Ben Knoble
  2026-06-17 17:21 ` Junio C Hamano
  0 siblings, 2 replies; 3+ messages in thread
From: Lutz Lengemann via GitGitGadget @ 2026-06-17 15:30 UTC (permalink / raw)
  To: git; +Cc: Lutz Lengemann, Lutz Lengemann

From: Lutz Lengemann <lutz@lengemann.net>

The zsh completion wrapper (__git_zsh_main) did not handle the global -C
option, so "git -C <path> <command> <TAB>" offered nothing and could not
complete a command's arguments.

Three things are needed to make it work, all scoped to -C:

  - Add -C to the _arguments specification, so completion no longer stops
    at it.

  - Advance __git_cmd_idx past any leading "-C <path>" options. The index
    is hard-coded to 1, i.e. the command is assumed to be the first
    argument; with -C present the command sits two words later for each
    -C, so the bash helpers otherwise look at the wrong word and produce
    nothing.

  - Collect the -C paths into __git_C_args, as __git_main does. The bash
    helpers run git to resolve aliases and list refs; without the -C
    paths they run in the current directory, so completion fails whenever
    the cwd is not the target repository or the command is an alias.

With these, "git -C <path> <command> <TAB>" completes the command, its
options and its arguments, including outside the repository, through
aliases, and with repeated -C options.

Signed-off-by: Lutz Lengemann <lutz@lengemann.net>
---
    completion: zsh: support completion after "git -C "
    
    This patch is intentionally scoped to -C, but the underlying problem is
    more general. The zsh wrapper hard-codes __git_cmd_idx=1, i.e. it
    assumes the command is always the first argument. That assumption breaks
    argument completion after any global option that precedes the command,
    not just -C — e.g. --git-dir, --work-tree, --namespace, -c, and
    -p/--paginate. After those, git <opt> <command> <TAB> currently
    completes the command name but not its arguments.
    
    The same approach generalizes cleanly: instead of skipping only leading
    -C options, walk all leading global options and their arguments to
    locate the command and its true index (mirroring the option scan in
    __git_main in git-completion.bash), while collecting -C into
    __git_C_args and --git-dir into __git_dir as today.
    
    I kept this revision narrow for reviewability and because git -C is the
    case where I miss the completion, but I'm happy to extend it to cover
    the other global options in a follow-up (or fold it into this patch) if
    that's preferred.

Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-2155%2Fmobilutz%2Fzsh-complete-global-C-v1
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-2155/mobilutz/zsh-complete-global-C-v1
Pull-Request: https://github.com/gitgitgadget/git/pull/2155

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

diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh
index c32186a977..323049be8b 100644
--- a/contrib/completion/git-completion.zsh
+++ b/contrib/completion/git-completion.zsh
@@ -227,6 +227,7 @@ __git_zsh_main ()
 		'(-p --paginate --no-pager)'{-p,--paginate}'[pipe all output into ''less'']' \
 		'(-p --paginate)--no-pager[do not pipe git output into a pager]' \
 		'--git-dir=-[set the path to the repository]: :_directories' \
+		'*-C[run as if git was started in <path>]: :_directories' \
 		'--bare[treat the repository as a bare repository]' \
 		'(- :)--version[prints the git suite version]' \
 		'--exec-path=-[path to where your core git programs are installed]:: :_directories' \
@@ -252,6 +253,14 @@ __git_zsh_main ()
 		;;
 	(arg)
 		local command="${words[1]}" __git_dir __git_cmd_idx=1
+		local -a __git_C_args
+		local -i i=2
+
+		while [[ ${orig_words[i]} == -C ]]; do
+			__git_C_args+=(-C ${orig_words[i+1]})
+			(( __git_cmd_idx += 2 ))
+			(( i += 2 ))
+		done
 
 		if (( $+opt_args[--bare] )); then
 			__git_dir='.'

base-commit: 0fae78c9d55efe705877ea537fe42c59164ccd94
-- 
gitgitgadget

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

end of thread, other threads:[~2026-06-17 17:21 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-06-17 15:30 [PATCH] completion: zsh: support completion after "git -C <path>" Lutz Lengemann via GitGitGadget
2026-06-17 17:17 ` Ben Knoble
2026-06-17 17:21 ` Junio C Hamano

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.