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

[PATCH 3/3] ref-filter: avoid backend filtering with --ignore-case

From
Jeff King <peff@peff.net>
Date
Jul 2, 2018, 21:12 UTC
Message-ID
<20180702211242.GC23324@sigill.intra.peff.net>
In-Reply-To
<20180702211100.GA20885@sigill.intra.peff.net>

When for-each-ref is used with --ignore-case, we expect match_name_as_path() to do a case-insensitive match. But there's an extra layer of filtering that happens before we even get there. Since commit cfe004a5a9 (ref-filter: limit traversal to prefix, 2017-05-22), we feed the prefix to the ref backend so that it can optimize the ref iteration.

There's no mechanism for us to tell the backend we're matching case-insensitively. And nor is there likely to be one anytime soon, since the packed backend relies on binary-searching the sorted list of refs. Let's just punt on this case. The extra filtering is an optimization that we simply can't do. We'll still give the correct answer via the filtering in match_name_as_path().

Signed-off-by: Jeff King <peff@peff.net>
---
 ref-filter.c            | 9 +++++++++
 t/t6300-for-each-ref.sh | 2 +-
 2 files changed, 10 insertions(+), 1 deletion(-)
diff --git a/ref-filter.c b/ref-filter.c
index 5c0cbde52b..52704c7be6 100644
--- a/ref-filter.c
+++ b/ref-filter.c
@@ -1868,6 +1868,15 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter,
 		return for_each_fullref_in("", cb, cb_data, broken);
 	}
 
+	if (filter->ignore_case) {
+		/*
+		 * we can't handle case-insensitive comparisons,
+		 * so just return everything and let the caller
+		 * sort it out.
+		 */
+		return for_each_fullref_in("", cb, cb_data, broken);
+	}
+
 	if (!filter->name_patterns[0]) {
 		/* no patterns; we have to look at everything */
 		return for_each_fullref_in("", cb, cb_data, broken);
diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh
index b2bc81103f..e0496da812 100755
--- a/t/t6300-for-each-ref.sh
+++ b/t/t6300-for-each-ref.sh
@@ -795,7 +795,7 @@ test_expect_success ':remotename and :remoteref' '
 	)
 '
 
-test_expect_failure 'for-each-ref --ignore-case ignores case' '
+test_expect_success 'for-each-ref --ignore-case ignores case' '
 	>expect &&
 	git for-each-ref --format="%(refname)" refs/heads/MASTER >actual &&
 	test_cmp expect actual &&
-- 
2.18.0.359.ge51c883f96
Previous: Jeff KingNext: Eric Sunshine
Message 4 of 5 in “un-break for-each-ref --ignore-case”
  1. 0/3 un-break for-each-ref --ignore-caseJeff King, Jul 2, 2018
  2. 1/3 t6300: add a test for --ignore-caseJeff King, Jul 2, 2018
  3. 2/3 for-each-ref: consistently pass WM_IGNORECASE flagJeff King, Jul 2, 2018
  4. 3/3 ref-filter: avoid backend filtering with --ignore-caseJeff King, Jul 2, 2018
  5. Eric SunshineJul 2, 2018

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.