All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Zakariyah Ali via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: Zakariyah Ali <zakariyahali100@gmail.com>,
	Zakariyah Ali <zakariyahali100@gmail.com>,
	Zakariyah Ali <zakariyahali100@gmail.com>
Subject: [PATCH v3 2/2] completion: hide dotfiles by default for path completion
Date: Sat, 20 Jun 2026 17:55:56 +0000	[thread overview]
Message-ID: <7482ee46454606a0883117d6cded6df809de710c.1781978156.git.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.2311.v3.git.git.1781978156.gitgitgadget@gmail.com>

From: Zakariyah Ali <zakariyahali100@gmail.com>

The previous implementation required callers to explicitly pass a
"hide-dotfiles" flag to __git_complete_index_file to avoid cluttering
completions with hidden files. This led to inconsistent behavior across
commands (e.g., `git add` and `git mv` behaved differently) and forced
callers to maintain repetitive logic.

As suggested by Junio C Hamano, this commit simplifies the logic:
1. __git_complete_index_file now unconditionally hides dotfiles when
   no match pattern is provided.
2. The awk loop in __git_index_files is refactored to check the dotfile
   condition in a single, obvious place after handling path dequoting,
   removing the previous duplication.
3. Callers no longer need to pass "hide-dotfiles".

This provides a cleaner API and ensures a consistent, expected behavior
where dotfiles are hidden unless explicitly requested by typing a dot.

Signed-off-by: Zakariyah Ali <zakariyahali100@gmail.com>
---
 contrib/completion/git-completion.bash | 65 ++++++++++++--------------
 t/t9902-completion.sh                  |  9 +++-
 2 files changed, 38 insertions(+), 36 deletions(-)

diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index e8f8fab125..b0b1b3c27a 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -638,20 +638,23 @@ __git_ls_files_helper ()
 }
 
 
-# __git_index_files accepts 1 to 4 arguments:
+# __git_index_files accepts 1 to 3 arguments:
 # 1: Options to pass to ls-files (required).
 # 2: A directory path (optional).
 #    If provided, only files within the specified directory are listed.
 #    Sub directories are never recursed.  Path must have a trailing
 #    slash.
 # 3: List only paths matching this path component (optional).
-# 4: Hide paths whose first component starts with a dot if this is
-#    "hide-dotfiles" and the third argument is empty (optional).
+#
+# If the third argument is empty, paths that begin with a dot (dotfiles)
+# are hidden. This matches user expectations where dotfiles are considered
+# hidden configuration files/directories and shouldn't clutter default
+# completions unless explicitly requested by typing a dot.
 __git_index_files ()
 {
-	local root="$2" match="$3" hide_dotfiles="${4-}"
+	local root="$2" match="$3"
 	local hide_dotfiles_awk=0
-	if [ "$hide_dotfiles" = "hide-dotfiles" ] && [ -z "$match" ]; then
+	if [ -z "$match" ]; then
 		hide_dotfiles_awk=1
 	fi
 
@@ -661,28 +664,22 @@ __git_index_files ()
 	}
 	END {
 		for (p in paths) {
-			if (substr(p, 1, 1) != "\"") {
-				# No special characters, easy!
-				if (hide_dotfiles == 1 && substr(p, 1, 1) == ".")
+			if (substr(p, 1, 1) == "\"") {
+				# The path is quoted.
+				p = dequote(p)
+				if (p == "")
 					continue
-				print pfx p
-				continue
-			}
-
-			# The path is quoted.
-			p = dequote(p)
-			if (p == "")
-				continue
 
-			# Even when a directory name itself does not contain
-			# any special characters, it will still be quoted if
-			# any of its (stripped) trailing path components do.
-			# Because of this we may have seen the same directory
-			# both quoted and unquoted.
-			if (p in paths)
-				# We have seen the same directory unquoted,
-				# skip it.
-				continue
+				# Even when a directory name itself does not contain
+				# any special characters, it will still be quoted if
+				# any of its (stripped) trailing path components do.
+				# Because of this we may have seen the same directory
+				# both quoted and unquoted.
+				if (p in paths)
+					# We have seen the same directory unquoted,
+					# skip it.
+					continue
+			}
 
 			if (hide_dotfiles == 1 && substr(p, 1, 1) == ".")
 				continue
@@ -731,15 +728,13 @@ __git_index_files ()
 	}'
 }
 
-# __git_complete_index_file accepts 1 or 2 arguments:
-# 1: the options to pass to ls-file
-# 2: Hide paths whose first component starts with a dot if this is
-#    "hide-dotfiles" and the current word is empty (optional).
+# __git_complete_index_file accepts 1 argument:
+# 1: the options to pass to ls-files
 #
 # The exception is --committable, which finds the files appropriate commit.
 __git_complete_index_file ()
 {
-	local dequoted_word pfx="" cur_ hide_dotfiles="${2-}"
+	local dequoted_word pfx="" cur_
 
 	__git_dequote "$cur"
 
@@ -752,7 +747,7 @@ __git_complete_index_file ()
 		cur_="$dequoted_word"
 	esac
 
-	__gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_" "$hide_dotfiles")"
+	__gitcomp_file_direct "$(__git_index_files "$1" "$pfx" "$cur_")"
 }
 
 # Lists branches from the local repository.
@@ -2176,7 +2171,7 @@ _git_ls_files ()
 
 	# XXX ignore options like --modified and always suggest all cached
 	# files.
-	__git_complete_index_file "--cached" hide-dotfiles
+	__git_complete_index_file "--cached"
 }
 
 _git_ls_remote ()
@@ -2409,9 +2404,9 @@ _git_mv ()
 	if [ $(__git_count_arguments "mv") -gt 0 ]; then
 		# We need to show both cached and untracked files (including
 		# empty directories) since this may not be the last argument.
-		__git_complete_index_file "--cached --others --directory" hide-dotfiles
+		__git_complete_index_file "--cached --others --directory"
 	else
-		__git_complete_index_file "--cached" hide-dotfiles
+		__git_complete_index_file "--cached"
 	fi
 }
 
@@ -3231,7 +3226,7 @@ _git_rm ()
 		;;
 	esac
 
-	__git_complete_index_file "--cached" hide-dotfiles
+	__git_complete_index_file "--cached"
 }
 
 _git_shortlog ()
diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh
index 02aaf71876..7a7594455c 100755
--- a/t/t9902-completion.sh
+++ b/t/t9902-completion.sh
@@ -2360,6 +2360,7 @@ test_expect_success 'setup for path completion tests' '
 	      "spaces in dir" \
 	      árvíztűrő &&
 	touch simple-dir/simple-file \
+	      simple-dir/.dotfile-in-dir \
 	      "spaces in dir/spaces in file" \
 	      "árvíztűrő/Сайн яваарай" &&
 	if test_have_prereq !MINGW &&
@@ -2380,6 +2381,11 @@ test_expect_success '__git_complete_index_file - simple' '
 	test_path_completion simple-dir/simple simple-dir/simple-file
 '
 
+test_expect_success '__git_complete_index_file - dotfiles' '
+	test_path_completion "simple-dir/" "simple-dir/simple-file" &&
+	test_path_completion "simple-dir/." "simple-dir/.dotfile-in-dir"
+'
+
 test_expect_success \
     '__git_complete_index_file - escaped characters on cmdline' '
 	test_path_completion spac "spaces in dir" &&  # Bash will turn this
@@ -2789,7 +2795,8 @@ test_expect_success 'complete files' '
 	echo "out_sorted" >> .gitignore &&
 
 	git add .gitignore &&
-	test_completion "git commit " ".gitignore" &&
+	test_completion "git commit " "" &&
+	test_completion "git commit ." ".gitignore" &&
 
 	git commit -m ignore &&
 
-- 
gitgitgadget

  parent reply	other threads:[~2026-06-20 17:56 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-05-24  2:36 [PATCH] completion: hide dotfiles for selected path completion Zakariyah Ali via GitGitGadget
2026-05-24 12:08 ` Junio C Hamano
2026-05-26 15:23 ` [PATCH v2] " Zakariyah Ali via GitGitGadget
2026-05-27  3:22   ` Junio C Hamano
2026-06-03 18:09   ` Follow-up and appreciation regarding Git contributions Zakariyah Ali
2026-06-10 18:56   ` [PATCH v2] completion: hide dotfiles for selected path completion Junio C Hamano
2026-06-20 17:55   ` [PATCH v3 0/2] " Zakariyah Ali via GitGitGadget
2026-06-20 17:55     ` [PATCH v3 1/2] " Zakariyah Ali via GitGitGadget
2026-06-20 17:55     ` Zakariyah Ali via GitGitGadget [this message]
2026-06-21  1:17     ` [PATCH v3 0/2] " 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=7482ee46454606a0883117d6cded6df809de710c.1781978156.git.gitgitgadget@gmail.com \
    --to=gitgitgadget@gmail.com \
    --cc=git@vger.kernel.org \
    --cc=zakariyahali100@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.