* [PATCH 0/2] completion of 'git [-C <dir>] checkout'
@ 2026-08-11 3:19 Junio C Hamano
2026-08-11 3:21 ` [PATCH 1/2] completion: no-op refactoring of checkout completion Junio C Hamano
` (2 more replies)
0 siblings, 3 replies; 4+ messages in thread
From: Junio C Hamano @ 2026-08-11 3:19 UTC (permalink / raw)
To: git
Cc: Philippe Blain, Britton Leo Kerin, Elijah Newren,
Rubén Justo, Patrick Steinhardt, D. Ben Knoble,
SZEDER Gábor
Continuing from the previous 'git [-C <dir>] diff' series, these two
patches correct completion for 'git checkout [-C <dir>] path<TAB>',
but without falling back to untracked paths, as "checkout paths out
of the index" is by definition about paths that appear in the index.
1/2: completion: no-op refactoring of checkout completion
2/2: completion: complete tracked paths for "git checkout"
contrib/completion/git-completion.bash | 86 ++++++++++++++------------
t/t9902-completion.sh | 27 ++++++++
2 files changed, 73 insertions(+), 40 deletions(-)
^ permalink raw reply [flat|nested] 4+ messages in thread
* [PATCH 1/2] completion: no-op refactoring of checkout completion
2026-08-11 3:19 [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
@ 2026-08-11 3:21 ` Junio C Hamano
2026-08-11 3:21 ` [PATCH 2/2] completion: complete tracked paths for "git checkout" Junio C Hamano
2026-08-11 4:04 ` [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
2 siblings, 0 replies; 4+ messages in thread
From: Junio C Hamano @ 2026-08-11 3:21 UTC (permalink / raw)
To: git
Cc: Philippe Blain, Britton Leo Kerin, Elijah Newren,
Rubén Justo, Patrick Steinhardt, D. Ben Knoble,
SZEDER Gábor
The 'git checkout' completion function punts very early when it sees
'--' on the command line, as it indicates that options or revisions
can no longer appear. By returning early, it allows the default
Bash action (which completes files in '$PWD') to kick in.
In preparation for changing what happens in the next step when
option or revision completion yields no matching candidates, or when
'--' is present, reorganize the control flow to avoid this early
return, and add explicit returns to the option completion branches.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
contrib/completion/git-completion.bash | 84 +++++++++++++-------------
1 file changed, 43 insertions(+), 41 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index d35b4f3024..38dec1cabe 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1735,49 +1735,51 @@ __git_checkout_default_dwim_mode ()
_git_checkout ()
{
- __git_has_doubledash && return
-
- local dwim_opt="$(__git_checkout_default_dwim_mode)"
-
- case "$prev" in
- -b|-B|--orphan)
- # Complete local branches (and DWIM branch
- # remote branch names) for an option argument
- # specifying a new branch name. This is for
- # convenience, assuming new branches are
- # possibly based on pre-existing branch names.
- __git_complete_refs $dwim_opt --mode="heads"
- return
- ;;
- *)
- ;;
- esac
+ if ! __git_has_doubledash; then
+ local dwim_opt="$(__git_checkout_default_dwim_mode)"
- case "$cur" in
- --conflict=*)
- __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
- ;;
- --*)
- __gitcomp_builtin checkout
- ;;
- *)
- # At this point, we've already handled special completion for
- # the arguments to -b/-B, and --orphan. There are 3 main
- # things left we can possibly complete:
- # 1) a start-point for -b/-B, -d/--detach, or --orphan
- # 2) a remote head, for --track
- # 3) an arbitrary reference, possibly including DWIM names
- #
+ case "$prev" in
+ -b|-B|--orphan)
+ # Complete local branches (and DWIM branch
+ # remote branch names) for an option argument
+ # specifying a new branch name. This is for
+ # convenience, assuming new branches are
+ # possibly based on pre-existing branch names.
+ __git_complete_refs $dwim_opt --mode="heads"
+ return
+ ;;
+ *)
+ ;;
+ esac
- if [ -n "$(__git_find_on_cmdline "-b -B -d --detach --orphan")" ]; then
- __git_complete_refs --mode="refs"
- elif [ -n "$(__git_find_on_cmdline "-t --track")" ]; then
- __git_complete_refs --mode="remote-heads"
- else
- __git_complete_refs $dwim_opt --mode="refs"
- fi
- ;;
- esac
+ case "$cur" in
+ --conflict=*)
+ __gitcomp "diff3 merge zdiff3" "" "${cur##--conflict=}"
+ return
+ ;;
+ --*)
+ __gitcomp_builtin checkout
+ return
+ ;;
+ *)
+ # At this point, we've already handled special completion for
+ # the arguments to -b/-B, and --orphan. There are 3 main
+ # things left we can possibly complete:
+ # 1) a start-point for -b/-B, -d/--detach, or --orphan
+ # 2) a remote head, for --track
+ # 3) an arbitrary reference, possibly including DWIM names
+ #
+
+ if [ -n "$(__git_find_on_cmdline "-b -B -d --detach --orphan")" ]; then
+ __git_complete_refs --mode="refs"
+ elif [ -n "$(__git_find_on_cmdline "-t --track")" ]; then
+ __git_complete_refs --mode="remote-heads"
+ else
+ __git_complete_refs $dwim_opt --mode="refs"
+ fi
+ ;;
+ esac
+ fi
}
__git_sequencer_inprogress_options="--continue --quit --abort --skip"
--
2.55.0-698-g3e60a4dc4e
^ permalink raw reply related [flat|nested] 4+ messages in thread
* [PATCH 2/2] completion: complete tracked paths for "git checkout"
2026-08-11 3:19 [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
2026-08-11 3:21 ` [PATCH 1/2] completion: no-op refactoring of checkout completion Junio C Hamano
@ 2026-08-11 3:21 ` Junio C Hamano
2026-08-11 4:04 ` [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
2 siblings, 0 replies; 4+ messages in thread
From: Junio C Hamano @ 2026-08-11 3:21 UTC (permalink / raw)
To: git
Cc: Philippe Blain, Britton Leo Kerin, Elijah Newren,
Rubén Justo, Patrick Steinhardt, D. Ben Knoble,
SZEDER Gábor
When completing arguments for "git checkout", _git_checkout()
delegates to __git_complete_refs(), which only completes revision
references. This is good, as mixing revisions and paths in a single
list from which the user can choose is confusing. However, if no
reference matches, or if "--" is given, _git_checkout() leaves
COMPREPLY empty. Bash then falls back to the default filename
completion in $PWD.
This fails when "git -C <path>" is used, as $PWD is not the target
repository.
Update _git_checkout() to use __git_complete_index_file() when "--"
is present, or when revision reference completion yields no matching
candidates, so that tracked paths are offered as candidates.
Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
contrib/completion/git-completion.bash | 4 ++++
t/t9902-completion.sh | 27 ++++++++++++++++++++++++++
2 files changed, 31 insertions(+)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 38dec1cabe..bd4b6e9247 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1780,6 +1780,10 @@ _git_checkout ()
;;
esac
fi
+
+ if [ ${#COMPREPLY[@]} -eq 0 ]; then
+ __git_complete_index_file
+ fi
}
__git_sequencer_inprogress_options="--continue --quit --abort --skip"
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 53a2bfb2ac..46fe94d8d5 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2713,6 +2713,33 @@ test_expect_success 'git -C <path> checkout uses the right repo' '
EOF
'
+test_expect_success 'git checkout completes tracked paths when no refs match' '
+ # file1 and file2 are tracked but ufile is not
+ # there is no ref that begins with f
+ test_completion "git checkout f" <<-\EOF &&
+ file1
+ file2
+ EOF
+ test_completion "git checkout -- f" <<-\EOF
+ file1
+ file2
+ EOF
+'
+
+test_expect_success 'git -C <path> checkout completes tracked paths in specified repo' '
+ test_when_finished "rm -rf repo-for-checkout" &&
+ git init repo-for-checkout &&
+ echo content >repo-for-checkout/otherfile &&
+ git -C repo-for-checkout add otherfile &&
+ git -C repo-for-checkout commit -m otherfile &&
+ test_completion "git -C repo-for-checkout checkout o" <<-\EOF &&
+ otherfile
+ EOF
+ test_completion "git -C repo-for-checkout checkout -- o" <<-\EOF
+ otherfile
+ EOF
+'
+
test_expect_success 'git diff completes tracked paths when no refs match' '
# file1 and file2 are tracked but file3 is not
test_completion "git diff f" <<-\EOF
--
2.55.0-698-g3e60a4dc4e
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [PATCH 0/2] completion of 'git [-C <dir>] checkout'
2026-08-11 3:19 [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
2026-08-11 3:21 ` [PATCH 1/2] completion: no-op refactoring of checkout completion Junio C Hamano
2026-08-11 3:21 ` [PATCH 2/2] completion: complete tracked paths for "git checkout" Junio C Hamano
@ 2026-08-11 4:04 ` Junio C Hamano
2 siblings, 0 replies; 4+ messages in thread
From: Junio C Hamano @ 2026-08-11 4:04 UTC (permalink / raw)
To: git
Cc: Philippe Blain, Britton Leo Kerin, Elijah Newren,
Rubén Justo, Patrick Steinhardt, D. Ben Knoble,
SZEDER Gábor
Junio C Hamano <gitster@pobox.com> writes:
> Continuing from the previous 'git [-C <dir>] diff' series, these two
> patches correct completion for 'git checkout [-C <dir>] path<TAB>',
> but without falling back to untracked paths, as "checkout paths out
> of the index" is by definition about paths that appear in the index.
I suppose I will add the 'untracked, too' final fallback, just like
'diff', because 'git checkout other-branch foo<TAB>' could resurrect
a path like 'foolish' that appears on 'other-branch' but not in the
currently checked-out branch (and thus not in the index). The
'foolish' file might also appear in the working tree as an untracked
path.
This is not particularly useful, however, as it is unlikely that a
file like 'foolish' tracked on another branch would be lying
around untracked in the working tree to begin with.
I did not, however, find any readily usable machinery in the
'git-completion.bash' script that allows completing a path within an
arbitrary tree. If such machinery were available, 'git checkout
other-branch foo<TAB>' could capture the output of 'git ls-tree -r
other-branch' and offer paths that begin with the given prefix.
Regardless, implementing this is beyond my 'git-completion-fu' right
now. As I mentioned, I barely managed the 'diff' completion as a
monkey-see-monkey-do patch series, and I would welcome others
building on top of this once the dust settles.
> 1/2: completion: no-op refactoring of checkout completion
> 2/2: completion: complete tracked paths for "git checkout"
>
> contrib/completion/git-completion.bash | 86 ++++++++++++++------------
> t/t9902-completion.sh | 27 ++++++++
> 2 files changed, 73 insertions(+), 40 deletions(-)
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2026-08-11 4:04 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-08-11 3:19 [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
2026-08-11 3:21 ` [PATCH 1/2] completion: no-op refactoring of checkout completion Junio C Hamano
2026-08-11 3:21 ` [PATCH 2/2] completion: complete tracked paths for "git checkout" Junio C Hamano
2026-08-11 4:04 ` [PATCH 0/2] completion of 'git [-C <dir>] checkout' 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