@@ -732,7 +732,8 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)
732
732
733
733
static struct dir_entry * dir_add_name (struct dir_struct * dir , const char * pathname , int len )
734
734
{
735
- if (cache_name_exists (pathname , len , ignore_case ))
735
+ if (!(dir -> flags & DIR_SHOW_IGNORED ) &&
736
+ cache_name_exists (pathname , len , ignore_case ))
736
737
return NULL ;
737
738
738
739
ALLOC_GROW (dir -> entries , dir -> nr + 1 , dir -> alloc );
@@ -834,8 +835,9 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
834
835
* traversal routine.
835
836
*
836
837
* Case 1: If we *already* have entries in the index under that
837
- * directory name, we always recurse into the directory to see
838
- * all the files.
838
+ * directory name, we recurse into the directory to see all the files,
839
+ * unless the directory is excluded and we want to show ignored
840
+ * directories
839
841
*
840
842
* Case 2: If we *already* have that directory name as a gitlink,
841
843
* we always continue to see it as a gitlink, regardless of whether
@@ -849,6 +851,9 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
849
851
* just a directory, unless "hide_empty_directories" is
850
852
* also true and the directory is empty, in which case
851
853
* we just ignore it entirely.
854
+ * if we are looking for ignored directories, look if it
855
+ * contains only ignored files to decide if it must be shown as
856
+ * ignored or not.
852
857
* (b) if it looks like a git directory, and we don't have
853
858
* 'no_gitlinks' set we treat it as a gitlink, and show it
854
859
* as a directory.
@@ -861,12 +866,15 @@ enum directory_treatment {
861
866
};
862
867
863
868
static enum directory_treatment treat_directory (struct dir_struct * dir ,
864
- const char * dirname , int len ,
869
+ const char * dirname , int len , int exclude ,
865
870
const struct path_simplify * simplify )
866
871
{
867
872
/* The "len-1" is to strip the final '/' */
868
873
switch (directory_exists_in_index (dirname , len - 1 )) {
869
874
case index_directory :
875
+ if ((dir -> flags & DIR_SHOW_OTHER_DIRECTORIES ) && exclude )
876
+ break ;
877
+
870
878
return recurse_into_directory ;
871
879
872
880
case index_gitdir :
@@ -886,13 +894,68 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
886
894
}
887
895
888
896
/* This is the "show_other_directories" case */
889
- if (!(dir -> flags & DIR_HIDE_EMPTY_DIRECTORIES ))
897
+
898
+ /*
899
+ * We are looking for ignored files and our directory is not ignored,
900
+ * check if it contains only ignored files
901
+ */
902
+ if ((dir -> flags & DIR_SHOW_IGNORED ) && !exclude ) {
903
+ int ignored ;
904
+ dir -> flags &= ~DIR_SHOW_IGNORED ;
905
+ dir -> flags |= DIR_HIDE_EMPTY_DIRECTORIES ;
906
+ ignored = read_directory_recursive (dir , dirname , len , 1 , simplify );
907
+ dir -> flags &= ~DIR_HIDE_EMPTY_DIRECTORIES ;
908
+ dir -> flags |= DIR_SHOW_IGNORED ;
909
+
910
+ return ignored ? ignore_directory : show_directory ;
911
+ }
912
+ if (!(dir -> flags & DIR_SHOW_IGNORED ) &&
913
+ !(dir -> flags & DIR_HIDE_EMPTY_DIRECTORIES ))
890
914
return show_directory ;
891
915
if (!read_directory_recursive (dir , dirname , len , 1 , simplify ))
892
916
return ignore_directory ;
893
917
return show_directory ;
894
918
}
895
919
920
+ /*
921
+ * Decide what to do when we find a file while traversing the
922
+ * filesystem. Mostly two cases:
923
+ *
924
+ * 1. We are looking for ignored files
925
+ * (a) File is ignored, include it
926
+ * (b) File is in ignored path, include it
927
+ * (c) File is not ignored, exclude it
928
+ *
929
+ * 2. Other scenarios, include the file if not excluded
930
+ *
931
+ * Return 1 for exclude, 0 for include.
932
+ */
933
+ static int treat_file (struct dir_struct * dir , struct strbuf * path , int exclude , int * dtype )
934
+ {
935
+ struct path_exclude_check check ;
936
+ int exclude_file = 0 ;
937
+
938
+ if (exclude )
939
+ exclude_file = !(dir -> flags & DIR_SHOW_IGNORED );
940
+ else if (dir -> flags & DIR_SHOW_IGNORED ) {
941
+ /* Always exclude indexed files */
942
+ struct cache_entry * ce = index_name_exists (& the_index ,
943
+ path -> buf , path -> len , ignore_case );
944
+
945
+ if (ce )
946
+ return 1 ;
947
+
948
+ path_exclude_check_init (& check , dir );
949
+
950
+ if (!path_excluded (& check , path -> buf , path -> len , dtype ))
951
+ exclude_file = 1 ;
952
+
953
+ path_exclude_check_clear (& check );
954
+ }
955
+
956
+ return exclude_file ;
957
+ }
958
+
896
959
/*
897
960
* This is an inexact early pruning of any recursive directory
898
961
* reading - if the path cannot possibly be in the pathspec,
@@ -1031,27 +1094,14 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1031
1094
if (dtype == DT_UNKNOWN )
1032
1095
dtype = get_dtype (de , path -> buf , path -> len );
1033
1096
1034
- /*
1035
- * Do we want to see just the ignored files?
1036
- * We still need to recurse into directories,
1037
- * even if we don't ignore them, since the
1038
- * directory may contain files that we do..
1039
- */
1040
- if (!exclude && (dir -> flags & DIR_SHOW_IGNORED )) {
1041
- if (dtype != DT_DIR )
1042
- return path_ignored ;
1043
- }
1044
-
1045
1097
switch (dtype ) {
1046
1098
default :
1047
1099
return path_ignored ;
1048
1100
case DT_DIR :
1049
1101
strbuf_addch (path , '/' );
1050
- switch (treat_directory (dir , path -> buf , path -> len , simplify )) {
1102
+
1103
+ switch (treat_directory (dir , path -> buf , path -> len , exclude , simplify )) {
1051
1104
case show_directory :
1052
- if (exclude != !!(dir -> flags
1053
- & DIR_SHOW_IGNORED ))
1054
- return path_ignored ;
1055
1105
break ;
1056
1106
case recurse_into_directory :
1057
1107
return path_recurse ;
@@ -1061,7 +1111,12 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1061
1111
break ;
1062
1112
case DT_REG :
1063
1113
case DT_LNK :
1064
- break ;
1114
+ switch (treat_file (dir , path , exclude , & dtype )) {
1115
+ case 1 :
1116
+ return path_ignored ;
1117
+ default :
1118
+ break ;
1119
+ }
1065
1120
}
1066
1121
return path_handled ;
1067
1122
}
0 commit comments