git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCHv2 14/14] completion: speed up branch and tag completion

From
SZEDER Gábor <szeder.dev@gmail.com>
Date
Mar 23, 2017, 15:29 UTC
Message-ID
<20170323152924.23944-15-szeder.dev@gmail.com>
In-Reply-To
<20170323152924.23944-1-szeder.dev@gmail.com>

Modify __git_heads() and __git_tags() and the few callsites they have, so we can let 'git for-each-ref' do all the hard work and these functions' output won't need any further processing or filtering before being handed over to Bash, resulting in faster branch and tag completion. These are some of the same tricks used in the previous commits to speed up refs completion, namely:

  - Extend both functions to accept prefix, current word and suffix
    positional parameters, all optional and all empty by default to
    keep the parameterless behavior unaltered.
  - Specify appropriate globbing patterns to 'git for-each-ref' to
    list only branches or tags matching the given current word
    parameter.
  - Modify the 'git for-each-ref --format=<...>' to include the given
    prefix and suffix.
  - Adjust all callsites to specify the proper prefix, current word
    and suffix parameters, and to fill COMPREPLY using
    __gitcomp_direct().
Signed-off-by: SZEDER Gábor <szeder.dev@gmail.com>
---
 contrib/completion/git-completion.bash | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash
index 86c7d93b8..bd07d9a74 100644
--- a/contrib/completion/git-completion.bash
+++ b/contrib/completion/git-completion.bash
@@ -352,14 +352,27 @@ __git_index_files ()
 	done | sort | uniq
 }
 
+# Lists branches from the local repository.
+# 1: A prefix to be added to each listed branch (optional).
+# 2: List only branches matching this word (optional; list all branches if
+#    unset or empty).
+# 3: A suffix to be appended to each listed branch (optional).
 __git_heads ()
 {
-	__git for-each-ref --format='%(refname:strip=2)' refs/heads
+	local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+	__git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+			"refs/heads/$cur_*" "refs/heads/$cur_*/**"
 }
 
+# Lists tags from the local repository.
+# Accepts the same positional parameters as __git_heads() above.
 __git_tags ()
 {
-	__git for-each-ref --format='%(refname:strip=2)' refs/tags
+	local pfx="${1-}" cur_="${2-}" sfx="${3-}"
+
+	__git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
+			"refs/tags/$cur_*" "refs/tags/$cur_*/**"
 }
 
 # Lists refs from the local (by default) or from a remote repository.
@@ -1183,7 +1196,7 @@ _git_branch ()
 		;;
 	*)
 		if [ $only_local_ref = "y" -a $has_r = "n" ]; then
-			__gitcomp_nl "$(__git_heads)"
+			__gitcomp_direct "$(__git_heads "" "$cur" " ")"
 		else
 			__git_complete_refs
 		fi
@@ -2178,7 +2191,7 @@ _git_config ()
 		;;
 	branch.*)
 		local pfx="${cur%.*}." cur_="${cur#*.}"
-		__gitcomp_nl "$(__git_heads)" "$pfx" "$cur_" "."
+		__gitcomp_direct "$(__git_heads "$pfx" "$cur_" ".")"
 		__gitcomp_nl_append $'autosetupmerge\nautosetuprebase\n' "$pfx" "$cur_"
 		return
 		;;
@@ -2824,7 +2837,7 @@ _git_tag ()
 		i="${words[c]}"
 		case "$i" in
 		-d|-v)
-			__gitcomp_nl "$(__git_tags)"
+			__gitcomp_direct "$(__git_tags "" "$cur" " ")"
 			return
 			;;
 		-f)
@@ -2839,7 +2852,7 @@ _git_tag ()
 		;;
 	-*|tag)
 		if [ $f = 1 ]; then
-			__gitcomp_nl "$(__git_tags)"
+			__gitcomp_direct "$(__git_tags "" "$cur" " ")"
 		fi
 		;;
 	*)
-- 
2.12.1.485.g1616aa492
Previous: SZEDER GáborNext: SZEDER Gábor
Message 13 of 22 in “[PATCHv2 00/14] completion: speed up refs completion”
  1. SZEDER GáborMar 23, 2017
  2. 01/14 completion: remove redundant __gitcomp_nl() options from _git_commit()SZEDER Gábor, Mar 23, 2017
  3. 05/14 completion: support excluding full refsSZEDER Gábor, Mar 23, 2017
  4. 04/14 completion: support completing fully qualified non-fast-forward refspecsSZEDER Gábor, Mar 23, 2017
  5. 07/14 completion: don't disambiguate short refsSZEDER Gábor, Mar 23, 2017
  6. Jeff KingMar 24, 2017
  7. 13/14 completion: fill COMPREPLY directly when completing fetch refspecsSZEDER Gábor, Mar 23, 2017
  8. 08/14 completion: let 'for-each-ref' and 'ls-remote' filter matching refsSZEDER Gábor, Mar 23, 2017
  9. Jeff KingMar 24, 2017
  10. SZEDER GáborMar 28, 2017
  11. 09/14 completion: let 'for-each-ref' strip the remote name from remote branchesSZEDER Gábor, Mar 23, 2017
  12. 10/14 completion: let 'for-each-ref' filter remote branches for 'checkout' DWIMerySZEDER Gábor, Mar 23, 2017
  13. 14/14 completion: speed up branch and tag completionSZEDER Gábor, Mar 23, 2017
  14. 12/14 completion: fill COMPREPLY directly when completing refsSZEDER Gábor, Mar 23, 2017
  15. 11/14 completion: let 'for-each-ref' sort remote branches for 'checkout' DWIMerySZEDER Gábor, Mar 23, 2017
  16. Jeff KingMar 24, 2017
  17. 03/14 completion: support completing full refs after '--option=refs/<TAB>'SZEDER Gábor, Mar 23, 2017
  18. 02/14 completion: wrap __git_refs() for better option parsingSZEDER Gábor, Mar 23, 2017
  19. 06/14 completion: don't disambiguate tags and branchesSZEDER Gábor, Mar 23, 2017
  20. SZEDER GáborMar 23, 2017
  21. Junio C HamanoMar 23, 2017
  22. Jeff KingMar 24, 2017

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.