411
for (i = 0; i < el->nr; i++)
412
free(el->excludes[i]);
413
free(el->excludes);
414
+ free(el->filebuf);
415
416
el->nr = 0;
417
el->excludes = NULL;
418
+ el->filebuf = NULL;
419
}
420
421
int add_excludes_from_file_to_list(const char *fname,
422
const char *base,
423
int baselen,
422
- char **buf_p,
424
struct exclude_list *el,
425
int check_index)
426
{
461
close(fd);
462
}
463
463
- if (buf_p)
464
- *buf_p = buf;
464
+ el->filebuf = buf;
465
entry = buf;
466
for (i = 0; i < size; i++) {
467
if (buf[i] == '\n') {
475
return 0;
476
}
477
478
+struct exclude_list *add_exclude_list(struct dir_struct *dir, int group_type)
479
+{
480
+ struct exclude_list *el;
481
+ struct exclude_list_group *group;
482
+
483
+ group = &dir->exclude_list_group[group_type];
484
+ ALLOC_GROW(group->el, group->nr + 1, group->alloc);
485
+ el = &group->el[group->nr++];
486
+ memset(el, 0, sizeof(*el));
487
+ return el;
488
+}
489
+
490
+/*
491
+ * Used to set up core.excludesfile and .git/info/exclude lists.
492
+ */
493
void add_excludes_from_file(struct dir_struct *dir, const char *fname)
494
{
480
- if (add_excludes_from_file_to_list(fname, "", 0, NULL,
481
- &dir->exclude_list[EXC_FILE], 0) < 0)
495
+ struct exclude_list *el;
496
+ el = add_exclude_list(dir, EXC_FILE);
497
+ if (add_excludes_from_file_to_list(fname, "", 0, el, 0) < 0)
498
die("cannot use %s as an exclude file", fname);
499
}
500
504
*/
505
static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
506
{
507
+ struct exclude_list_group *group;
508
struct exclude_list *el;
509
struct exclude_stack *stk = NULL;
510
int current;
513
(baselen + strlen(dir->exclude_per_dir) >= PATH_MAX))
514
return; /* too long a path -- ignore */
515
499
- /* Pop the directories that are not the prefix of the path being checked. */
500
- el = &dir->exclude_list[EXC_DIRS];
516
+ group = &dir->exclude_list_group[EXC_DIRS];
517
+
518
+ /* Pop the exclude lists from the EXCL_DIRS exclude_list_group
519
+ * which originate from directories not in the prefix of the
520
+ * path being checked. */
521
while ((stk = dir->exclude_stack) != NULL) {
522
if (stk->baselen <= baselen &&
523
!strncmp(dir->basebuf, base, stk->baselen))
524
break;
525
+ el = &group->el[dir->exclude_stack->exclude_ix];
526
dir->exclude_stack = stk->prev;
506
- while (stk->exclude_ix < el->nr)
507
- free(el->excludes[--el->nr]);
508
- free(stk->filebuf);
527
+ clear_exclude_list(el);
528
free(stk);
529
+ group->nr--;
530
}
531
532
/* Read from the parent directories and push them down. */
547
}
548
stk->prev = dir->exclude_stack;
549
stk->baselen = cp - base;
530
- stk->exclude_ix = el->nr;
550
memcpy(dir->basebuf + current, base + current,
551
stk->baselen - current);
552
strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir);
553
+ el = add_exclude_list(dir, EXC_DIRS);
554
+ stk->exclude_ix = group->nr - 1;
555
add_excludes_from_file_to_list(dir->basebuf,
556
dir->basebuf, stk->baselen,
536
- &stk->filebuf, el, 1);
557
+ el, 1);
558
dir->exclude_stack = stk;
559
current = stk->baselen;
560
}
700
int *dtype_p)
701
{
702
int pathlen = strlen(pathname);
682
- int st;
703
+ int i, j;
704
+ struct exclude_list_group *group;
705
struct exclude *exclude;
706
const char *basename = strrchr(pathname, '/');
707
basename = (basename) ? basename+1 : pathname;
708
709
prep_exclude(dir, pathname, basename-pathname);
688
- for (st = EXC_CMDL; st <= EXC_FILE; st++) {
689
- exclude = last_exclude_matching_from_list(
690
- pathname, pathlen, basename, dtype_p,
691
- &dir->exclude_list[st]);
692
- if (exclude)
693
- return exclude;
710
+
711
+ for (i = EXC_CMDL; i <= EXC_FILE; i++) {
712
+ group = &dir->exclude_list_group[i];
713
+ for (j = group->nr - 1; j >= 0; j--) {
714
+ exclude = last_exclude_matching_from_list(
715
+ pathname, pathlen, basename, dtype_p,
716
+ &group->el[j]);
717
+ if (exclude)
718
+ return exclude;
719
+ }
720
}
721
return NULL;
722
}