aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJunio C Hamano <gitster@pobox.com>2025-03-26 16:26:10 +0900
committerJunio C Hamano <gitster@pobox.com>2025-03-26 16:26:10 +0900
commitdef5e32bc56617c8f43ddc17ee5785abf1b865d4 (patch)
tree3b7df4907bfd10d3d718325fc9c9e66c6ed82b8e
parentde35b7b3ffb6e642b47f748eb38e31182377fb0a (diff)
parent10e8a9352bcc7b21a64e0b321f302cf900ac8c77 (diff)
downloadgit-def5e32bc56617c8f43ddc17ee5785abf1b865d4.tar.gz
Merge branch 'tb/refs-exclude-fixes'
The refname exclusion logic in the packed-ref backend has been broken for some time, which confused upload-pack to advertise different set of refs. This has been corrected. * tb/refs-exclude-fixes: refs.c: stop matching non-directory prefixes in exclude patterns refs.c: remove empty '--exclude' patterns
-rw-r--r--refs.c20
-rwxr-xr-xt/t1419-exclude-refs.sh26
2 files changed, 44 insertions, 2 deletions
diff --git a/refs.c b/refs.c
index 118465271d..50c3849845 100644
--- a/refs.c
+++ b/refs.c
@@ -1699,6 +1699,24 @@ struct ref_iterator *refs_ref_iterator_begin(
enum do_for_each_ref_flags flags)
{
struct ref_iterator *iter;
+ struct strvec normalized_exclude_patterns = STRVEC_INIT;
+
+ if (exclude_patterns) {
+ for (size_t i = 0; exclude_patterns[i]; i++) {
+ const char *pattern = exclude_patterns[i];
+ size_t len = strlen(pattern);
+ if (!len)
+ continue;
+
+ if (pattern[len - 1] == '/')
+ strvec_push(&normalized_exclude_patterns, pattern);
+ else
+ strvec_pushf(&normalized_exclude_patterns, "%s/",
+ pattern);
+ }
+
+ exclude_patterns = normalized_exclude_patterns.v;
+ }
if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) {
static int ref_paranoia = -1;
@@ -1719,6 +1737,8 @@ struct ref_iterator *refs_ref_iterator_begin(
if (trim)
iter = prefix_ref_iterator_begin(iter, "", trim);
+ strvec_clear(&normalized_exclude_patterns);
+
return iter;
}
diff --git a/t/t1419-exclude-refs.sh b/t/t1419-exclude-refs.sh
index c04eeb7211..04797aee59 100755
--- a/t/t1419-exclude-refs.sh
+++ b/t/t1419-exclude-refs.sh
@@ -46,6 +46,10 @@ test_expect_success 'setup' '
echo "create refs/heads/$name/$i $base" || return 1
done || return 1
done >in &&
+ for i in 5 6 7
+ do
+ echo "create refs/heads/bar/4/$i $base" || return 1
+ done >>in &&
echo "delete refs/heads/main" >>in &&
git update-ref --stdin <in &&
@@ -99,9 +103,17 @@ test_expect_success 'adjacent, non-overlapping excluded regions' '
esac
'
-test_expect_success 'overlapping excluded regions' '
+test_expect_success 'non-directory excluded regions' '
for_each_ref__exclude refs/heads refs/heads/ba refs/heads/baz >actual 2>perf &&
- for_each_ref refs/heads/foo refs/heads/quux >expect &&
+ for_each_ref refs/heads/bar refs/heads/foo refs/heads/quux >expect &&
+
+ test_cmp expect actual &&
+ assert_jumps 1 perf
+'
+
+test_expect_success 'overlapping excluded regions' '
+ for_each_ref__exclude refs/heads refs/heads/bar refs/heads/bar/4 >actual 2>perf &&
+ for_each_ref refs/heads/baz refs/heads/foo refs/heads/quux >expect &&
test_cmp expect actual &&
assert_jumps 1 perf
@@ -155,4 +167,14 @@ test_expect_success 'meta-characters are discarded' '
assert_no_jumps perf
'
+test_expect_success 'empty string exclude pattern is ignored' '
+ git update-ref refs/heads/loose $(git rev-parse refs/heads/foo/1) &&
+
+ for_each_ref__exclude refs/heads "" >actual 2>perf &&
+ for_each_ref >expect &&
+
+ test_cmp expect actual &&
+ assert_no_jumps perf
+'
+
test_done