All of lore.kernel.org
 help / color / mirror / Atom feed
From: Junio C Hamano <gitster@pobox.com>
To: git@vger.kernel.org
Cc: Elijah Newren <newren@gmail.com>
Subject: [PATCH v3 3/3] completion: 'git checkout' completes untracked paths as a last resort
Date: Thu, 13 Aug 2026 12:12:34 -0700	[thread overview]
Message-ID: <20260813191234.1066662-4-gitster@pobox.com> (raw)
In-Reply-To: <20260813191234.1066662-1-gitster@pobox.com>

We taught 'git checkout' to first try to complete revisions (unless
'--' is present on the command line) and, failing that, to complete
tracked paths.  If this yields nothing, it lets the Bash default,
which offers paths in $PWD, kick in.

Teach it to complete untracked paths before giving up and letting
the Bash default kick in.  With this change,

    $ git -C another-directory checkout un<TAB>

finds the 'untracked' file in another-directory and offers it as a
completion candidate.

Note that this is of somewhat dubious value, as an untracked path by
definition does not exist in the index, so checking it out from the
index would not work well.  Even when used to check out the path
from a different branch, it is still of dubious value because it is
unlikely that a path tracked in another branch is lying untracked in
the working tree, as switching from a branch with the path to a
branch without it will normally remove the file in the working tree.

A better behavior probably is to detect the tree-ish argument on
the command line and offer paths with the given prefix as candidates,
but there is no __git_complete_from_tree() helper readily usable,
so mark this as #leftoverbits to wait for another day.

Signed-off-by: Junio C Hamano <gitster@pobox.com>
---
 contrib/completion/git-completion.bash |  4 ++++
 t/t9902-completion.sh                  | 21 +++++++++++++++++++--
 2 files changed, 23 insertions(+), 2 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 0eecfcbf8b..e6dce62d3c 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -1784,6 +1784,10 @@ _git_checkout ()
 	if [ ${#COMPREPLY[@]} -eq 0 ]; then
 		__git_complete_index_file ""
 	fi
+
+	if [ ${#COMPREPLY[@]} -eq 0 ]; then
+		__git_complete_index_file "--others --directory"
+	fi
 }
 
 __git_sequencer_inprogress_options="--continue --quit --abort --skip"
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 13fa5c65c3..e8418f069b 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2727,9 +2727,19 @@ test_expect_success 'git checkout completes tracked paths when no refs match' '
 	EOF
 '
 
+test_expect_success 'git checkout completes untracked paths, too' '
+	# ufile is not tracked and there is no ref that begins with u
+	test_completion "git checkout u" <<-\EOF &&
+	ufile
+	EOF
+	test_completion "git checkout -- u" <<-\EOF
+	ufile
+	EOF
+'
+
 test_expect_success 'git -C <path> checkout completes paths in specified repo' '
 	# otherfile is tracked, oops is not
-	# lostfile is tracked but lost
+	# lostfile is tracked but lost, ufile is untracked.
 	test_when_finished "rm -rf repo-for-checkout" &&
 	git init repo-for-checkout &&
 	echo content >repo-for-checkout/otherfile &&
@@ -2738,6 +2748,7 @@ test_expect_success 'git -C <path> checkout completes paths in specified repo' '
 	git -C repo-for-checkout add lostfile &&
 	git -C repo-for-checkout commit -m otherfile &&
 	echo untracked >repo-for-checkout/oops &&
+	echo untracked >repo-for-checkout/ufile &&
 	rm -f repo-for-checkout/lostfile &&
 	test_completion "git -C repo-for-checkout checkout o" <<-\EOF &&
 	otherfile
@@ -2748,9 +2759,15 @@ test_expect_success 'git -C <path> checkout completes paths in specified repo' '
 	test_completion "git -C repo-for-checkout checkout l" <<-\EOF &&
 	lostfile
 	EOF
-	test_completion "git -C repo-for-checkout checkout -- l" <<-\EOF
+	test_completion "git -C repo-for-checkout checkout -- l" <<-\EOF &&
 	lostfile
 	EOF
+	test_completion "git -C repo-for-checkout checkout u" <<-\EOF &&
+	ufile
+	EOF
+	test_completion "git -C repo-for-checkout checkout -- u" <<-\EOF
+	ufile
+	EOF
 '
 
 test_expect_success 'git diff completes tracked paths when no refs match' '
-- 
2.55.0-759-g9dcc51a0fd


  parent reply	other threads:[~2026-08-13 19:12 UTC|newest]

Thread overview: 19+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 16:32   ` Ben Knoble
2026-08-11 17:25     ` Junio C Hamano
2026-08-11  4:04 ` [PATCH 0/2] completion of 'git [-C <dir>] checkout' Junio C Hamano
2026-08-11 16:33   ` Ben Knoble
2026-08-12  1:45     ` Junio C Hamano
2026-08-12 16:48 ` [PATCH v2 0/3] " Junio C Hamano
2026-08-12 16:48   ` [PATCH v2 1/3] completion: no-op refactoring of checkout completion Junio C Hamano
2026-08-12 16:48   ` [PATCH v2 2/3] completion: complete tracked paths for "git checkout" Junio C Hamano
2026-08-12 16:48   ` [PATCH v2 3/3] completion: 'git checkout' completes untracked paths as a last resort Junio C Hamano
2026-08-12 19:57     ` Elijah Newren
2026-08-12 20:18       ` Junio C Hamano
2026-08-13 19:12 ` [PATCH v3 0/3] completion of 'git [-C <dir>] checkout' Junio C Hamano
2026-08-13 19:12   ` [PATCH v3 1/3] completion: no-op refactoring of checkout completion Junio C Hamano
2026-08-13 19:12   ` [PATCH v3 2/3] completion: complete tracked paths for "git checkout" Junio C Hamano
2026-08-13 19:12   ` Junio C Hamano [this message]
2026-08-14  1:53   ` [PATCH v3 0/3] completion of 'git [-C <dir>] checkout' Elijah Newren

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=20260813191234.1066662-4-gitster@pobox.com \
    --to=gitster@pobox.com \
    --cc=git@vger.kernel.org \
    --cc=newren@gmail.com \
    /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.