ref-filter: avoid backend filtering with --ignore-case
authorJeff King <peff@peff.net>
Mon, 2 Jul 2018 21:12:42 +0000 (17:12 -0400)
committerJunio C Hamano <gitster@pobox.com>
Tue, 3 Jul 2018 21:49:37 +0000 (14:49 -0700)
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. 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>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
ref-filter.c
t/t6300-for-each-ref.sh
index c0e257c79e536c136d59dd5e8cd34251d7ed1b0e..85057234eed4a444f285932ab7d8aaa62a3ca943 100644 (file)
@@ -1769,6 +1769,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);
index 1adb9580b1edda08afd6035f92c05e977b40fbe3..3bb901d50f5bdaadd74a4c869991c6315c66a8bc 100755 (executable)
@@ -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 &&