@@ -625,6 +625,84 @@ static int get_dtype(struct dirent *de, const char *path, int len)
625
625
return dtype ;
626
626
}
627
627
628
+ enum path_treatment {
629
+ path_ignored ,
630
+ path_handled ,
631
+ path_recurse ,
632
+ };
633
+
634
+ static enum path_treatment treat_path (struct dir_struct * dir ,
635
+ struct dirent * de ,
636
+ char * path , int path_max ,
637
+ int baselen ,
638
+ const struct path_simplify * simplify ,
639
+ int * len )
640
+ {
641
+ int dtype , exclude ;
642
+
643
+ if (is_dot_or_dotdot (de -> d_name ) || !strcmp (de -> d_name , ".git" ))
644
+ return path_ignored ;
645
+ * len = strlen (de -> d_name );
646
+ /* Ignore overly long pathnames! */
647
+ if (* len + baselen + 8 > path_max )
648
+ return path_ignored ;
649
+ memcpy (path + baselen , de -> d_name , * len + 1 );
650
+ * len += baselen ;
651
+ if (simplify_away (path , * len , simplify ))
652
+ return path_ignored ;
653
+
654
+ dtype = DTYPE (de );
655
+ exclude = excluded (dir , path , & dtype );
656
+ if (exclude && (dir -> flags & DIR_COLLECT_IGNORED )
657
+ && in_pathspec (path , * len , simplify ))
658
+ dir_add_ignored (dir , path , * len );
659
+
660
+ /*
661
+ * Excluded? If we don't explicitly want to show
662
+ * ignored files, ignore it
663
+ */
664
+ if (exclude && !(dir -> flags & DIR_SHOW_IGNORED ))
665
+ return path_ignored ;
666
+
667
+ if (dtype == DT_UNKNOWN )
668
+ dtype = get_dtype (de , path , * len );
669
+
670
+ /*
671
+ * Do we want to see just the ignored files?
672
+ * We still need to recurse into directories,
673
+ * even if we don't ignore them, since the
674
+ * directory may contain files that we do..
675
+ */
676
+ if (!exclude && (dir -> flags & DIR_SHOW_IGNORED )) {
677
+ if (dtype != DT_DIR )
678
+ return path_ignored ;
679
+ }
680
+
681
+ switch (dtype ) {
682
+ default :
683
+ return path_ignored ;
684
+ case DT_DIR :
685
+ memcpy (path + * len , "/" , 2 );
686
+ (* len )++ ;
687
+ switch (treat_directory (dir , path , * len , simplify )) {
688
+ case show_directory :
689
+ if (exclude != !!(dir -> flags
690
+ & DIR_SHOW_IGNORED ))
691
+ return path_ignored ;
692
+ break ;
693
+ case recurse_into_directory :
694
+ return path_recurse ;
695
+ case ignore_directory :
696
+ return path_ignored ;
697
+ }
698
+ break ;
699
+ case DT_REG :
700
+ case DT_LNK :
701
+ break ;
702
+ }
703
+ return path_handled ;
704
+ }
705
+
628
706
/*
629
707
* Read a directory tree. We currently ignore anything but
630
708
* directories, regular files and symlinks. That's because git
@@ -634,7 +712,10 @@ static int get_dtype(struct dirent *de, const char *path, int len)
634
712
* Also, we ignore the name ".git" (even if it is not a directory).
635
713
* That likely will not change.
636
714
*/
637
- static int read_directory_recursive (struct dir_struct * dir , const char * base , int baselen , int check_only , const struct path_simplify * simplify )
715
+ static int read_directory_recursive (struct dir_struct * dir ,
716
+ const char * base , int baselen ,
717
+ int check_only ,
718
+ const struct path_simplify * simplify )
638
719
{
639
720
DIR * fdir = opendir (* base ? base : "." );
640
721
int contents = 0 ;
@@ -645,70 +726,16 @@ static int read_directory_recursive(struct dir_struct *dir, const char *base, in
645
726
memcpy (path , base , baselen );
646
727
647
728
while ((de = readdir (fdir )) != NULL ) {
648
- int len , dtype ;
649
- int exclude ;
650
-
651
- if (is_dot_or_dotdot (de -> d_name ) ||
652
- !strcmp (de -> d_name , ".git" ))
653
- continue ;
654
- len = strlen (de -> d_name );
655
- /* Ignore overly long pathnames! */
656
- if (len + baselen + 8 > sizeof (path ))
729
+ int len ;
730
+ switch (treat_path (dir , de , path , sizeof (path ),
731
+ baselen , simplify , & len )) {
732
+ case path_recurse :
733
+ contents += read_directory_recursive
734
+ (dir , path , len , 0 , simplify );
657
735
continue ;
658
- memcpy (path + baselen , de -> d_name , len + 1 );
659
- len = baselen + len ;
660
- if (simplify_away (path , len , simplify ))
736
+ case path_ignored :
661
737
continue ;
662
-
663
- dtype = DTYPE (de );
664
- exclude = excluded (dir , path , & dtype );
665
- if (exclude && (dir -> flags & DIR_COLLECT_IGNORED )
666
- && in_pathspec (path , len , simplify ))
667
- dir_add_ignored (dir , path ,len );
668
-
669
- /*
670
- * Excluded? If we don't explicitly want to show
671
- * ignored files, ignore it
672
- */
673
- if (exclude && !(dir -> flags & DIR_SHOW_IGNORED ))
674
- continue ;
675
-
676
- if (dtype == DT_UNKNOWN )
677
- dtype = get_dtype (de , path , len );
678
-
679
- /*
680
- * Do we want to see just the ignored files?
681
- * We still need to recurse into directories,
682
- * even if we don't ignore them, since the
683
- * directory may contain files that we do..
684
- */
685
- if (!exclude && (dir -> flags & DIR_SHOW_IGNORED )) {
686
- if (dtype != DT_DIR )
687
- continue ;
688
- }
689
-
690
- switch (dtype ) {
691
- default :
692
- continue ;
693
- case DT_DIR :
694
- memcpy (path + len , "/" , 2 );
695
- len ++ ;
696
- switch (treat_directory (dir , path , len , simplify )) {
697
- case show_directory :
698
- if (exclude != !!(dir -> flags
699
- & DIR_SHOW_IGNORED ))
700
- continue ;
701
- break ;
702
- case recurse_into_directory :
703
- contents += read_directory_recursive (dir ,
704
- path , len , 0 , simplify );
705
- continue ;
706
- case ignore_directory :
707
- continue ;
708
- }
709
- break ;
710
- case DT_REG :
711
- case DT_LNK :
738
+ case path_handled :
712
739
break ;
713
740
}
714
741
contents ++ ;
0 commit comments