From 9984228f1fe600dae3df7f1d8472e348bb1eef6f Mon Sep 17 00:00:00 2001 From: Lutz Lengemann Date: Mon, 17 Aug 2026 20:44:02 +0200 Subject: [PATCH] completion: zsh: support completion after "git -C " The zsh completion wrapper does not handle the global -C option, so git -C offers nothing. -C is not part of the _arguments specification, and the wrapper hard-codes __git_cmd_idx=1, i.e. it assumes that the command is the first argument, so the bash helpers look at the wrong word. The latter is not specific to -C; the assumption breaks after any global option, e.g. "git -p checkout " does not complete branch names. Add -C to the specification, and find the command by skipping over the global options and, where they take one, their arguments, as __git_main in git-completion.bash does. The index is one less than zsh's, as the helpers count the words from zero. Collect the paths given to -C into __git_C_args, or else the helpers run git in the current directory and fail to resolve the aliases and refs of the repository the command runs in. The argument of a -C is still completed without regard for the -C options before it, i.e. "git -C dir -C " offers the directories in ".", not the ones in "dir". Signed-off-by: Lutz Lengemann --- contrib/completion/git-completion.zsh | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index c32186a977e2d1..d5c526665b2b31 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 ]: :_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' \ @@ -251,7 +252,29 @@ __git_zsh_main () done ;; (arg) - local command="${words[1]}" __git_dir __git_cmd_idx=1 + local command="${words[1]}" __git_dir __git_cmd_idx + local -a __git_C_args + local -i i=2 + + while (( i <= $#orig_words )); do + case ${orig_words[i]} in + -C) + __git_C_args+=(-C ${orig_words[i+1]}) + (( i++ )) + ;; + -c|--git-dir|--work-tree|--namespace) + (( i++ )) + ;; + -*) + ;; + *) + break + ;; + esac + (( i++ )) + done + + __git_cmd_idx=$(( i - 1 )) if (( $+opt_args[--bare] )); then __git_dir='.'