572
return 0;
573
}
574
575
+/*
576
+ * Perform matching on the leading non-wildcard part of
577
+ * pathspec. item->nowildcard_len must be greater than zero. Return
578
+ * non-zero if base is matched.
579
+ */
580
+static int match_wildcard_base(const struct pathspec_item *item,
581
+ const char *base, int baselen,
582
+ int *matched)
583
+{
584
+ const char *match = item->match;
585
+ /* the wildcard part is not considered in this function */
586
+ int matchlen = item->nowildcard_len;
587
+
588
+ if (baselen) {
589
+ int dirlen;
590
+ /*
591
+ * Return early if base is longer than the
592
+ * non-wildcard part but it does not match.
593
+ */
594
+ if (baselen >= matchlen) {
595
+ *matched = matchlen;
596
+ return !strncmp(base, match, matchlen);
597
+ }
598
+
599
+ dirlen = matchlen;
600
+ while (dirlen && match[dirlen - 1] != '/')
601
+ dirlen--;
602
+
603
+ /*
604
+ * Return early if base is shorter than the
605
+ * non-wildcard part but it does not match. Note that
606
+ * base ends with '/' so we are sure it really matches
607
+ * directory
608
+ */
609
+ if (strncmp(base, match, baselen))
610
+ return 0;
611
+ *matched = baselen;
612
+ } else
613
+ *matched = 0;
614
+ /*
615
+ * we could have checked entry against the non-wildcard part
616
+ * that is not in base and does similar never_interesting
617
+ * optimization as in match_entry. For now just be happy with
618
+ * base comparison.
619
+ */
620
+ return entry_interesting;
621
+}
622
+
623
/*
624
* Is a tree entry interesting given the pathspec we have?
625
*
650
const struct pathspec_item *item = ps->items+i;
651
const char *match = item->match;
652
const char *base_str = base->buf + base_offset;
605
- int matchlen = item->len;
653
+ int matchlen = item->len, matched = 0;
654
655
if (baselen >= matchlen) {
656
/* If it doesn't match, move along... */
695
if (item->nowildcard_len == item->len)
696
continue;
697
698
+ if (item->nowildcard_len &&
699
+ !match_wildcard_base(item, base_str, baselen, &matched))
700
+ return entry_not_interesting;
701
+
702
/*
703
* Concatenate base and entry->path into one and do
704
* fnmatch() on it.
705
+ *
706
+ * While we could avoid concatenation in certain cases
707
+ * [1], which saves a memcpy and potentially a
708
+ * realloc, it turns out not worth it. Measurement on
709
+ * linux-2.6 does not show any clear improvements,
710
+ * partly because of the nowildcard_len optimization
711
+ * in git_fnmatch(). Avoid micro-optimizations here.
712
+ *
713
+ * [1] if match_wildcard_base() says the base
714
+ * directory is already matched, we only need to match
715
+ * the rest, which is shorter so _in theory_ faster.
716
*/
717
718
strbuf_add(base, entry->path, pathlen);