From: "Lutz Lengemann via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Lutz Lengemann <lutz@lengemann.net>, Lutz Lengemann <lutz@lengemann.net>
Subject: [PATCH] completion: zsh: support completion after "git -C <path>"
Date: Wed, 17 Jun 2026 15:30:55 +0000 [thread overview]
Message-ID: <pull.2155.git.1781710256081.gitgitgadget@gmail.com> (raw)
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
next reply other threads:[~2026-06-17 15:30 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-06-17 15:30 Lutz Lengemann via GitGitGadget [this message]
2026-06-17 17:17 ` [PATCH] completion: zsh: support completion after "git -C <path>" Ben Knoble
2026-06-17 17:21 ` Junio C Hamano
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=pull.2155.git.1781710256081.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=git@vger.kernel.org \
--cc=lutz@lengemann.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
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.