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 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.