2
2
* This handles recursive filename detection with exclude
3
3
* files, index knowledge etc..
4
4
*
5
+ * See Documentation/technical/api-directory-listing.txt
6
+ *
5
7
* Copyright (C) Linus Torvalds, 2005-2006
6
8
* Junio Hamano, 2005-2006
7
9
*/
@@ -377,7 +379,7 @@ void parse_exclude_pattern(const char **pattern,
377
379
}
378
380
379
381
void add_exclude (const char * string , const char * base ,
380
- int baselen , struct exclude_list * which )
382
+ int baselen , struct exclude_list * el )
381
383
{
382
384
struct exclude * x ;
383
385
int patternlen ;
@@ -401,8 +403,8 @@ void add_exclude(const char *string, const char *base,
401
403
x -> base = base ;
402
404
x -> baselen = baselen ;
403
405
x -> flags = flags ;
404
- ALLOC_GROW (which -> excludes , which -> nr + 1 , which -> alloc );
405
- which -> excludes [which -> nr ++ ] = x ;
406
+ ALLOC_GROW (el -> excludes , el -> nr + 1 , el -> alloc );
407
+ el -> excludes [el -> nr ++ ] = x ;
406
408
}
407
409
408
410
static void * read_skip_worktree_file_from_index (const char * path , size_t * size )
@@ -428,7 +430,11 @@ static void *read_skip_worktree_file_from_index(const char *path, size_t *size)
428
430
return data ;
429
431
}
430
432
431
- void free_excludes (struct exclude_list * el )
433
+ /*
434
+ * Frees memory within el which was allocated for exclude patterns and
435
+ * the file buffer. Does not free el itself.
436
+ */
437
+ void clear_exclude_list (struct exclude_list * el )
432
438
{
433
439
int i ;
434
440
@@ -444,7 +450,7 @@ int add_excludes_from_file_to_list(const char *fname,
444
450
const char * base ,
445
451
int baselen ,
446
452
char * * buf_p ,
447
- struct exclude_list * which ,
453
+ struct exclude_list * el ,
448
454
int check_index )
449
455
{
450
456
struct stat st ;
@@ -493,7 +499,7 @@ int add_excludes_from_file_to_list(const char *fname,
493
499
if (buf [i ] == '\n' ) {
494
500
if (entry != buf + i && entry [0 ] != '#' ) {
495
501
buf [i - (i && buf [i - 1 ] == '\r' )] = 0 ;
496
- add_exclude (entry , base , baselen , which );
502
+ add_exclude (entry , base , baselen , el );
497
503
}
498
504
entry = buf + i + 1 ;
499
505
}
@@ -508,6 +514,10 @@ void add_excludes_from_file(struct dir_struct *dir, const char *fname)
508
514
die ("cannot use %s as an exclude file" , fname );
509
515
}
510
516
517
+ /*
518
+ * Loads the per-directory exclude list for the substring of base
519
+ * which has a char length of baselen.
520
+ */
511
521
static void prep_exclude (struct dir_struct * dir , const char * base , int baselen )
512
522
{
513
523
struct exclude_list * el ;
@@ -518,7 +528,7 @@ static void prep_exclude(struct dir_struct *dir, const char *base, int baselen)
518
528
(baselen + strlen (dir -> exclude_per_dir ) >= PATH_MAX ))
519
529
return ; /* too long a path -- ignore */
520
530
521
- /* Pop the ones that are not the prefix of the path being checked. */
531
+ /* Pop the directories that are not the prefix of the path being checked. */
522
532
el = & dir -> exclude_list [EXC_DIRS ];
523
533
while ((stk = dir -> exclude_stack ) != NULL ) {
524
534
if (stk -> baselen <= baselen &&
@@ -629,22 +639,26 @@ int match_pathname(const char *pathname, int pathlen,
629
639
ignore_case ? FNM_CASEFOLD : 0 ) == 0 ;
630
640
}
631
641
632
- /* Scan the list and let the last match determine the fate.
633
- * Return 1 for exclude, 0 for include and -1 for undecided.
642
+ /*
643
+ * Scan the given exclude list in reverse to see whether pathname
644
+ * should be ignored. The first match (i.e. the last on the list), if
645
+ * any, determines the fate. Returns the exclude_list element which
646
+ * matched, or NULL for undecided.
634
647
*/
635
- int excluded_from_list (const char * pathname ,
636
- int pathlen , const char * basename , int * dtype ,
637
- struct exclude_list * el )
648
+ static struct exclude * last_exclude_matching_from_list (const char * pathname ,
649
+ int pathlen ,
650
+ const char * basename ,
651
+ int * dtype ,
652
+ struct exclude_list * el )
638
653
{
639
654
int i ;
640
655
641
656
if (!el -> nr )
642
- return -1 ; /* undefined */
657
+ return NULL ; /* undefined */
643
658
644
659
for (i = el -> nr - 1 ; 0 <= i ; i -- ) {
645
660
struct exclude * x = el -> excludes [i ];
646
661
const char * exclude = x -> pattern ;
647
- int to_exclude = x -> flags & EXC_FLAG_NEGATIVE ? 0 : 1 ;
648
662
int prefix = x -> nowildcardlen ;
649
663
650
664
if (x -> flags & EXC_FLAG_MUSTBEDIR ) {
@@ -659,43 +673,80 @@ int excluded_from_list(const char *pathname,
659
673
pathlen - (basename - pathname ),
660
674
exclude , prefix , x -> patternlen ,
661
675
x -> flags ))
662
- return to_exclude ;
676
+ return x ;
663
677
continue ;
664
678
}
665
679
666
680
assert (x -> baselen == 0 || x -> base [x -> baselen - 1 ] == '/' );
667
681
if (match_pathname (pathname , pathlen ,
668
682
x -> base , x -> baselen ? x -> baselen - 1 : 0 ,
669
683
exclude , prefix , x -> patternlen , x -> flags ))
670
- return to_exclude ;
684
+ return x ;
671
685
}
686
+ return NULL ; /* undecided */
687
+ }
688
+
689
+ /*
690
+ * Scan the list and let the last match determine the fate.
691
+ * Return 1 for exclude, 0 for include and -1 for undecided.
692
+ */
693
+ int is_excluded_from_list (const char * pathname ,
694
+ int pathlen , const char * basename , int * dtype ,
695
+ struct exclude_list * el )
696
+ {
697
+ struct exclude * exclude ;
698
+ exclude = last_exclude_matching_from_list (pathname , pathlen , basename , dtype , el );
699
+ if (exclude )
700
+ return exclude -> flags & EXC_FLAG_NEGATIVE ? 0 : 1 ;
672
701
return -1 ; /* undecided */
673
702
}
674
703
675
- static int excluded (struct dir_struct * dir , const char * pathname , int * dtype_p )
704
+ /*
705
+ * Loads the exclude lists for the directory containing pathname, then
706
+ * scans all exclude lists to determine whether pathname is excluded.
707
+ * Returns the exclude_list element which matched, or NULL for
708
+ * undecided.
709
+ */
710
+ static struct exclude * last_exclude_matching (struct dir_struct * dir ,
711
+ const char * pathname ,
712
+ int * dtype_p )
676
713
{
677
714
int pathlen = strlen (pathname );
678
715
int st ;
716
+ struct exclude * exclude ;
679
717
const char * basename = strrchr (pathname , '/' );
680
718
basename = (basename ) ? basename + 1 : pathname ;
681
719
682
720
prep_exclude (dir , pathname , basename - pathname );
683
721
for (st = EXC_CMDL ; st <= EXC_FILE ; st ++ ) {
684
- switch (excluded_from_list (pathname , pathlen , basename ,
685
- dtype_p , & dir -> exclude_list [st ])) {
686
- case 0 :
687
- return 0 ;
688
- case 1 :
689
- return 1 ;
690
- }
722
+ exclude = last_exclude_matching_from_list (
723
+ pathname , pathlen , basename , dtype_p ,
724
+ & dir -> exclude_list [st ]);
725
+ if (exclude )
726
+ return exclude ;
691
727
}
728
+ return NULL ;
729
+ }
730
+
731
+ /*
732
+ * Loads the exclude lists for the directory containing pathname, then
733
+ * scans all exclude lists to determine whether pathname is excluded.
734
+ * Returns 1 if true, otherwise 0.
735
+ */
736
+ static int is_excluded (struct dir_struct * dir , const char * pathname , int * dtype_p )
737
+ {
738
+ struct exclude * exclude =
739
+ last_exclude_matching (dir , pathname , dtype_p );
740
+ if (exclude )
741
+ return exclude -> flags & EXC_FLAG_NEGATIVE ? 0 : 1 ;
692
742
return 0 ;
693
743
}
694
744
695
745
void path_exclude_check_init (struct path_exclude_check * check ,
696
746
struct dir_struct * dir )
697
747
{
698
748
check -> dir = dir ;
749
+ check -> exclude = NULL ;
699
750
strbuf_init (& check -> path , 256 );
700
751
}
701
752
@@ -705,49 +756,77 @@ void path_exclude_check_clear(struct path_exclude_check *check)
705
756
}
706
757
707
758
/*
708
- * Is this name excluded? This is for a caller like show_files() that
709
- * do not honor directory hierarchy and iterate through paths that are
710
- * possibly in an ignored directory.
759
+ * For each subdirectory in name, starting with the top-most, checks
760
+ * to see if that subdirectory is excluded, and if so, returns the
761
+ * corresponding exclude structure. Otherwise, checks whether name
762
+ * itself (which is presumably a file) is excluded.
711
763
*
712
764
* A path to a directory known to be excluded is left in check->path to
713
765
* optimize for repeated checks for files in the same excluded directory.
714
766
*/
715
- int path_excluded (struct path_exclude_check * check ,
716
- const char * name , int namelen , int * dtype )
767
+ struct exclude * last_exclude_matching_path (struct path_exclude_check * check ,
768
+ const char * name , int namelen ,
769
+ int * dtype )
717
770
{
718
771
int i ;
719
772
struct strbuf * path = & check -> path ;
773
+ struct exclude * exclude ;
720
774
721
775
/*
722
776
* we allow the caller to pass namelen as an optimization; it
723
777
* must match the length of the name, as we eventually call
724
- * excluded () on the whole name string.
778
+ * is_excluded () on the whole name string.
725
779
*/
726
780
if (namelen < 0 )
727
781
namelen = strlen (name );
728
782
783
+ /*
784
+ * If path is non-empty, and name is equal to path or a
785
+ * subdirectory of path, name should be excluded, because
786
+ * it's inside a directory which is already known to be
787
+ * excluded and was previously left in check->path.
788
+ */
729
789
if (path -> len &&
730
790
path -> len <= namelen &&
731
791
!memcmp (name , path -> buf , path -> len ) &&
732
792
(!name [path -> len ] || name [path -> len ] == '/' ))
733
- return 1 ;
793
+ return check -> exclude ;
734
794
735
795
strbuf_setlen (path , 0 );
736
796
for (i = 0 ; name [i ]; i ++ ) {
737
797
int ch = name [i ];
738
798
739
799
if (ch == '/' ) {
740
800
int dt = DT_DIR ;
741
- if (excluded (check -> dir , path -> buf , & dt ))
742
- return 1 ;
801
+ exclude = last_exclude_matching (check -> dir ,
802
+ path -> buf , & dt );
803
+ if (exclude ) {
804
+ check -> exclude = exclude ;
805
+ return exclude ;
806
+ }
743
807
}
744
808
strbuf_addch (path , ch );
745
809
}
746
810
747
811
/* An entry in the index; cannot be a directory with subentries */
748
812
strbuf_setlen (path , 0 );
749
813
750
- return excluded (check -> dir , name , dtype );
814
+ return last_exclude_matching (check -> dir , name , dtype );
815
+ }
816
+
817
+ /*
818
+ * Is this name excluded? This is for a caller like show_files() that
819
+ * do not honor directory hierarchy and iterate through paths that are
820
+ * possibly in an ignored directory.
821
+ */
822
+ int is_path_excluded (struct path_exclude_check * check ,
823
+ const char * name , int namelen , int * dtype )
824
+ {
825
+ struct exclude * exclude =
826
+ last_exclude_matching_path (check , name , namelen , dtype );
827
+ if (exclude )
828
+ return exclude -> flags & EXC_FLAG_NEGATIVE ? 0 : 1 ;
829
+ return 0 ;
751
830
}
752
831
753
832
static struct dir_entry * dir_entry_new (const char * pathname , int len )
@@ -1047,7 +1126,7 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1047
1126
const struct path_simplify * simplify ,
1048
1127
int dtype , struct dirent * de )
1049
1128
{
1050
- int exclude = excluded (dir , path -> buf , & dtype );
1129
+ int exclude = is_excluded (dir , path -> buf , & dtype );
1051
1130
if (exclude && (dir -> flags & DIR_COLLECT_IGNORED )
1052
1131
&& exclude_matches_pathspec (path -> buf , path -> len , simplify ))
1053
1132
dir_add_ignored (dir , path -> buf , path -> len );
0 commit comments