@@ -1015,6 +1015,25 @@ static void populate_excluded_jump_list(struct packed_ref_iterator *iter,
if (!excluded_patterns)
return;
+ for (pattern = excluded_patterns; *pattern; pattern++) {
+ /*
+ * We also can't feed any excludes from hidden refs
+ * config sections, since later rules may override
+ * previous ones. For example, with rules "refs/foo" and
+ * "!refs/foo/bar", we should show "refs/foo/bar" (and
+ * everything underneath it), but the earlier exclusion
+ * would cause us to skip all of "refs/foo". We likewise
+ * don't implement the namespace stripping required for
+ * '^' rules.
+ *
+ * Both are possible to do, but complicated, so avoid
+ * populating the jump list at all if we see either of
+ * these patterns.
+ */
+ if (**pattern == '!' || **pattern == '^')
+ return;
+ }
+
for (pattern = excluded_patterns; *pattern; pattern++) {
struct jump_list_entry *e;
@@ -119,4 +119,13 @@ test_expect_success 'meta-characters are discarded' '
assert_no_jumps
'
+test_expect_success 'complex hidden ref rules are discarded' '
+ for_each_ref__exclude refs/heads refs/heads/foo "!refs/heads/foo/1" \
+ >actual 2>perf &&
+ for_each_ref >expect &&
+
+ test_cmp expect actual &&
+ assert_no_jumps
+'
+
test_done
In subsequent commits, we'll teach `receive-pack` and `upload-pack` to use the new skip-list feature in the packed-refs iterator by ignoring references which are mentioned via its respective hideRefs lists. However, the packed-ref skip lists cannot handle un-hiding rules (that begin with '!'), or namespace comparisons (that begin with '^'). Detect and avoid these cases by falling back to the normal enumeration without a skip list when such patterns exist. Signed-off-by: Taylor Blau <me@ttaylorr.com> --- refs/packed-backend.c | 19 +++++++++++++++++++ t/t1419-exclude-refs.sh | 9 +++++++++ 2 files changed, 28 insertions(+)