From: "Alison Winters via GitGitGadget" <gitgitgadget@gmail.com>
To: git@vger.kernel.org
Cc: "Taylor Blau" <me@ttaylorr.com>,
"SZEDER Gábor" <szeder.dev@gmail.com>,
"Alison Winters" <alisonatwork@outlook.com>
Subject: [PATCH v2 0/2] add case insensitivity option to bash completion
Date: Mon, 21 Nov 2022 00:26:57 +0000 [thread overview]
Message-ID: <pull.1374.v2.git.git.1668990419.gitgitgadget@gmail.com> (raw)
In-Reply-To: <pull.1374.git.git.1667669315.gitgitgadget@gmail.com>
In 3bb16a8bf2 (tag, branch, for-each-ref: add --ignore-case for sorting and
filtering, 2016-12-04), support was added for filtering and sorting refs in
a case insensitive way. This is a behavior that seems appropriate to enable
with shell completion. Many shells provide case insensitive completion as an
option, even on filesystems that remain case sensitive.
This patch adds a new variable that, when set, will allow Bash completion to
use the --ignore-case option to match refs. Additionally, some basic support
is implemented to match pseudorefs like HEAD.
Changes since v1:
* Improved comments and commit messages to clarify behavior on case
sensitive filesystems
* Replaced some lengthy if blocks with inline substitution
* As a result of the above change, GIT_COMPLETION_IGNORE_CASE no longer
needs to be set to "1" and now just needs to be present in the
environment to work
* Removed unnecessary exports in tests
Alison Winters (2):
completion: add optional ignore-case when matching refs
completion: add case-insensitive match of pseudorefs
contrib/completion/git-completion.bash | 26 +++++++++++++++++++---
t/t9902-completion.sh | 30 ++++++++++++++++++++++++++
2 files changed, 53 insertions(+), 3 deletions(-)
base-commit: a0789512c5a4ae7da935cd2e419f253cb3cb4ce7
Published-As: https://github.com/gitgitgadget/git/releases/tag/pr-git-1374%2Falisonatwork%2Fbash-insensitive-v2
Fetch-It-Via: git fetch https://github.com/gitgitgadget/git pr-git-1374/alisonatwork/bash-insensitive-v2
Pull-Request: https://github.com/git/git/pull/1374
Range-diff vs v1:
1: cef9a12b575 ! 1: a261a94877a completion: add optional ignore-case when matching refs
@@ Metadata
## Commit message ##
completion: add optional ignore-case when matching refs
- If GIT_COMPLETION_IGNORE_CASE=1 is set, --ignore-case will be added to
- git for-each-ref calls so that branches and tags can be matched case
- insensitively.
+ If GIT_COMPLETION_IGNORE_CASE is set, --ignore-case will be added to
+ git for-each-ref calls so that refs can be matched case insensitively,
+ even when running on case sensitive filesystems.
Signed-off-by: Alison Winters <alisonatwork@outlook.com>
@@ contrib/completion/git-completion.bash
+#
+# GIT_COMPLETION_IGNORE_CASE
+#
-+# When set to "1", suggest refs that match case insensitively (e.g.,
-+# completing "FOO" on "git checkout f<TAB>").
++# When set, uses for-each-ref '--ignore-case' to find refs that match
++# case insensitively, even on systems with case sensitive file systems
++# (e.g., completing tag name "FOO" on "git checkout f<TAB>").
case "$COMP_WORDBREAKS" in
*:*) : great ;;
-@@ contrib/completion/git-completion.bash: __git_complete_index_file ()
- __git_heads ()
- {
+@@ contrib/completion/git-completion.bash: __git_heads ()
local pfx="${1-}" cur_="${2-}" sfx="${3-}"
-+ local ignore_case=""
-+
-+ if test "${GIT_COMPLETION_IGNORE_CASE-}" = "1"
-+ then
-+ ignore_case="--ignore-case"
-+ fi
__git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
-+ $ignore_case \
++ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"refs/heads/$cur_*" "refs/heads/$cur_*/**"
}
-@@ contrib/completion/git-completion.bash: __git_heads ()
- __git_remote_heads ()
- {
+@@ contrib/completion/git-completion.bash: __git_remote_heads ()
local pfx="${1-}" cur_="${2-}" sfx="${3-}"
-+ local ignore_case=""
-+
-+ if test "${GIT_COMPLETION_IGNORE_CASE-}" = "1"
-+ then
-+ ignore_case="--ignore-case"
-+ fi
__git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
-+ $ignore_case \
++ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"refs/remotes/$cur_*" "refs/remotes/$cur_*/**"
}
-@@ contrib/completion/git-completion.bash: __git_remote_heads ()
- __git_tags ()
- {
+@@ contrib/completion/git-completion.bash: __git_tags ()
local pfx="${1-}" cur_="${2-}" sfx="${3-}"
-+ local ignore_case=""
-+
-+ if test "${GIT_COMPLETION_IGNORE_CASE-}" = "1"
-+ then
-+ ignore_case="--ignore-case"
-+ fi
__git for-each-ref --format="${pfx//\%/%%}%(refname:strip=2)$sfx" \
-+ $ignore_case \
++ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"refs/tags/$cur_*" "refs/tags/$cur_*/**"
}
@@ contrib/completion/git-completion.bash: __git_dwim_remote_heads ()
- {
- local pfx="${1-}" cur_="${2-}" sfx="${3-}"
- local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
-+ local ignore_case=""
-+
-+ if test "${GIT_COMPLETION_IGNORE_CASE-}" = "1"
-+ then
-+ ignore_case="--ignore-case"
-+ fi
-
- # employ the heuristic used by git checkout and git switch
- # Try to find a remote branch that cur_es the completion word
# but only output if the branch name is unique
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
--sort="refname:strip=3" \
-+ $ignore_case \
++ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"refs/remotes/*/$cur_*" "refs/remotes/*/$cur_*/**" | \
uniq -u
}
-@@ contrib/completion/git-completion.bash: __git_refs ()
- local pfx="${3-}" cur_="${4-$cur}" sfx="${5-}"
- local match="${4-}"
- local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
-+ local ignore_case=""
-
- __git_find_repo_path
- dir="$__git_repo_path"
-@@ contrib/completion/git-completion.bash: __git_refs ()
- fi
- fi
-
-+ if test "${GIT_COMPLETION_IGNORE_CASE-}" = "1"
-+ then
-+ ignore_case="--ignore-case"
-+ fi
-+
- if [ "$list_refs_from" = path ]; then
- if [[ "$cur_" == ^* ]]; then
- pfx="$pfx^"
@@ contrib/completion/git-completion.bash: __git_refs ()
;;
esac
__git_dir="$dir" __git for-each-ref --format="$fer_pfx%($format)$sfx" \
-+ $ignore_case \
++ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"${refs[@]}"
if [ -n "$track" ]; then
__git_dwim_remote_heads "$pfx" "$match" "$sfx"
@@ contrib/completion/git-completion.bash: __git_refs ()
$match*) echo "${pfx}HEAD$sfx" ;;
esac
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
-+ $ignore_case \
++ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
"refs/remotes/$remote/$match*" \
"refs/remotes/$remote/$match*/**"
else
@@ t/t9902-completion.sh: test_expect_success 'checkout completes ref names' '
+
+test_expect_success 'checkout matches case insensitively with GIT_COMPLETION_IGNORE_CASE' '
+ (
-+ . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
-+ GIT_COMPLETION_IGNORE_CASE=1 && export GIT_COMPLETION_IGNORE_CASE &&
++ GIT_COMPLETION_IGNORE_CASE=1 &&
+ test_completion "git checkout M" <<-\EOF
+ main Z
+ mybranch Z
2: c455e855395 ! 2: 480f6554c93 completion: add case-insensitive match of pseudorefs
@@ Metadata
## Commit message ##
completion: add case-insensitive match of pseudorefs
- When GIT_COMPLETION_IGNORE_CASE=1, also allow lowercase completion text
- like "head" to match HEAD and other pseudorefs.
+ When GIT_COMPLETION_IGNORE_CASE is set, also allow lowercase completion
+ text like "head" to match uppercase HEAD and other pseudorefs.
Signed-off-by: Alison Winters <alisonatwork@outlook.com>
@@ contrib/completion/git-completion.bash: __git_refs ()
local match="${4-}"
+ local umatch="${4-}"
local fer_pfx="${pfx//\%/%%}" # "escape" for-each-ref format specifiers
- local ignore_case=""
+ __git_find_repo_path
@@ contrib/completion/git-completion.bash: __git_refs ()
- if test "${GIT_COMPLETION_IGNORE_CASE-}" = "1"
- then
- ignore_case="--ignore-case"
-+ # use tr instead of ${match,^^} to preserve bash 3.2 compatibility
-+ umatch=$(echo "$match" | tr a-z A-Z 2> /dev/null || echo "$match")
+ fi
fi
++ if test "${GIT_COMPLETION_IGNORE_CASE:+1}" = "1"
++ then
++ # uppercase with tr instead of ${match,^^} for bash 3.2 compatibility
++ umatch=$(echo "$match" | tr a-z A-Z 2>/dev/null || echo "$match")
++ fi
++
if [ "$list_refs_from" = path ]; then
-@@ contrib/completion/git-completion.bash: __git_refs ()
+ if [[ "$cur_" == ^* ]]; then
+ pfx="$pfx^"
fer_pfx="$fer_pfx^"
cur_=${cur_#^}
match=${match#^}
@@ contrib/completion/git-completion.bash: __git_refs ()
+ $match*|$umatch*) echo "${pfx}HEAD$sfx" ;;
esac
__git for-each-ref --format="$fer_pfx%(refname:strip=3)$sfx" \
- $ignore_case \
+ ${GIT_COMPLETION_IGNORE_CASE+--ignore-case} \
@@ contrib/completion/git-completion.bash: __git_refs ()
else
local query_symref
@@ t/t9902-completion.sh: test_expect_success 'checkout matches case insensitively
+
+test_expect_success 'checkout completes pseudo refs case insensitively with GIT_COMPLETION_IGNORE_CASE' '
+ (
-+ . "$GIT_BUILD_DIR/contrib/completion/git-completion.bash" &&
-+ GIT_COMPLETION_IGNORE_CASE=1 && export GIT_COMPLETION_IGNORE_CASE &&
++ GIT_COMPLETION_IGNORE_CASE=1 &&
+ test_completion "git checkout h" <<-\EOF
+ HEAD Z
+ EOF
--
gitgitgadget
next prev parent reply other threads:[~2022-11-21 0:27 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-05 17:28 [PATCH 0/2] add case insensitivity option to bash completion Alison Winters via GitGitGadget
2022-11-05 17:28 ` [PATCH 1/2] completion: add optional ignore-case when matching refs Alison Winters via GitGitGadget
2022-11-20 20:24 ` SZEDER Gábor
2022-11-05 17:28 ` [PATCH 2/2] completion: add case-insensitive match of pseudorefs Alison Winters via GitGitGadget
2022-11-20 20:42 ` SZEDER Gábor
2022-11-20 20:46 ` SZEDER Gábor
2022-11-08 3:00 ` [PATCH 0/2] add case insensitivity option to bash completion Taylor Blau
2022-11-21 0:26 ` Alison Winters via GitGitGadget [this message]
2022-11-21 0:26 ` [PATCH v2 1/2] completion: add optional ignore-case when matching refs Alison Winters via GitGitGadget
2022-11-21 0:26 ` [PATCH v2 2/2] completion: add case-insensitive match of pseudorefs Alison Winters via GitGitGadget
2022-11-29 2:38 ` [PATCH 0/2] add case insensitivity option to bash completion Junio C Hamano
2022-11-29 15:56 ` Alison Winters
2022-11-29 17:40 ` Ævar Arnfjörð Bjarmason
2022-11-30 0:37 ` Alison Winters
2022-11-30 3:08 ` 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=pull.1374.v2.git.git.1668990419.gitgitgadget@gmail.com \
--to=gitgitgadget@gmail.com \
--cc=alisonatwork@outlook.com \
--cc=git@vger.kernel.org \
--cc=me@ttaylorr.com \
--cc=szeder.dev@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).