@@ -842,7 +842,8 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)
842842
843843static struct dir_entry * dir_add_name (struct dir_struct * dir , const char * pathname , int len )
844844{
845- if (cache_name_exists (pathname , len , ignore_case ))
845+ if (!(dir -> flags & DIR_SHOW_IGNORED ) &&
846+ cache_name_exists (pathname , len , ignore_case ))
846847 return NULL ;
847848
848849 ALLOC_GROW (dir -> entries , dir -> nr + 1 , dir -> alloc );
@@ -944,8 +945,9 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
944945 * traversal routine.
945946 *
946947 * Case 1: If we *already* have entries in the index under that
947- * directory name, we always recurse into the directory to see
948- * all the files.
948+ * directory name, we recurse into the directory to see all the files,
949+ * unless the directory is excluded and we want to show ignored
950+ * directories
949951 *
950952 * Case 2: If we *already* have that directory name as a gitlink,
951953 * we always continue to see it as a gitlink, regardless of whether
@@ -959,6 +961,9 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len)
959961 * just a directory, unless "hide_empty_directories" is
960962 * also true and the directory is empty, in which case
961963 * we just ignore it entirely.
964+ * if we are looking for ignored directories, look if it
965+ * contains only ignored files to decide if it must be shown as
966+ * ignored or not.
962967 * (b) if it looks like a git directory, and we don't have
963968 * 'no_gitlinks' set we treat it as a gitlink, and show it
964969 * as a directory.
@@ -971,12 +976,15 @@ enum directory_treatment {
971976};
972977
973978static enum directory_treatment treat_directory (struct dir_struct * dir ,
974- const char * dirname , int len ,
979+ const char * dirname , int len , int exclude ,
975980 const struct path_simplify * simplify )
976981{
977982 /* The "len-1" is to strip the final '/' */
978983 switch (directory_exists_in_index (dirname , len - 1 )) {
979984 case index_directory :
985+ if ((dir -> flags & DIR_SHOW_OTHER_DIRECTORIES ) && exclude )
986+ break ;
987+
980988 return recurse_into_directory ;
981989
982990 case index_gitdir :
@@ -996,13 +1004,68 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
9961004 }
9971005
9981006 /* This is the "show_other_directories" case */
999- if (!(dir -> flags & DIR_HIDE_EMPTY_DIRECTORIES ))
1007+
1008+ /*
1009+ * We are looking for ignored files and our directory is not ignored,
1010+ * check if it contains only ignored files
1011+ */
1012+ if ((dir -> flags & DIR_SHOW_IGNORED ) && !exclude ) {
1013+ int ignored ;
1014+ dir -> flags &= ~DIR_SHOW_IGNORED ;
1015+ dir -> flags |= DIR_HIDE_EMPTY_DIRECTORIES ;
1016+ ignored = read_directory_recursive (dir , dirname , len , 1 , simplify );
1017+ dir -> flags &= ~DIR_HIDE_EMPTY_DIRECTORIES ;
1018+ dir -> flags |= DIR_SHOW_IGNORED ;
1019+
1020+ return ignored ? ignore_directory : show_directory ;
1021+ }
1022+ if (!(dir -> flags & DIR_SHOW_IGNORED ) &&
1023+ !(dir -> flags & DIR_HIDE_EMPTY_DIRECTORIES ))
10001024 return show_directory ;
10011025 if (!read_directory_recursive (dir , dirname , len , 1 , simplify ))
10021026 return ignore_directory ;
10031027 return show_directory ;
10041028}
10051029
1030+ /*
1031+ * Decide what to do when we find a file while traversing the
1032+ * filesystem. Mostly two cases:
1033+ *
1034+ * 1. We are looking for ignored files
1035+ * (a) File is ignored, include it
1036+ * (b) File is in ignored path, include it
1037+ * (c) File is not ignored, exclude it
1038+ *
1039+ * 2. Other scenarios, include the file if not excluded
1040+ *
1041+ * Return 1 for exclude, 0 for include.
1042+ */
1043+ static int treat_file (struct dir_struct * dir , struct strbuf * path , int exclude , int * dtype )
1044+ {
1045+ struct path_exclude_check check ;
1046+ int exclude_file = 0 ;
1047+
1048+ if (exclude )
1049+ exclude_file = !(dir -> flags & DIR_SHOW_IGNORED );
1050+ else if (dir -> flags & DIR_SHOW_IGNORED ) {
1051+ /* Always exclude indexed files */
1052+ struct cache_entry * ce = index_name_exists (& the_index ,
1053+ path -> buf , path -> len , ignore_case );
1054+
1055+ if (ce )
1056+ return 1 ;
1057+
1058+ path_exclude_check_init (& check , dir );
1059+
1060+ if (!is_path_excluded (& check , path -> buf , path -> len , dtype ))
1061+ exclude_file = 1 ;
1062+
1063+ path_exclude_check_clear (& check );
1064+ }
1065+
1066+ return exclude_file ;
1067+ }
1068+
10061069/*
10071070 * This is an inexact early pruning of any recursive directory
10081071 * reading - if the path cannot possibly be in the pathspec,
@@ -1141,27 +1204,14 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
11411204 if (dtype == DT_UNKNOWN )
11421205 dtype = get_dtype (de , path -> buf , path -> len );
11431206
1144- /*
1145- * Do we want to see just the ignored files?
1146- * We still need to recurse into directories,
1147- * even if we don't ignore them, since the
1148- * directory may contain files that we do..
1149- */
1150- if (!exclude && (dir -> flags & DIR_SHOW_IGNORED )) {
1151- if (dtype != DT_DIR )
1152- return path_ignored ;
1153- }
1154-
11551207 switch (dtype ) {
11561208 default :
11571209 return path_ignored ;
11581210 case DT_DIR :
11591211 strbuf_addch (path , '/' );
1160- switch (treat_directory (dir , path -> buf , path -> len , simplify )) {
1212+
1213+ switch (treat_directory (dir , path -> buf , path -> len , exclude , simplify )) {
11611214 case show_directory :
1162- if (exclude != !!(dir -> flags
1163- & DIR_SHOW_IGNORED ))
1164- return path_ignored ;
11651215 break ;
11661216 case recurse_into_directory :
11671217 return path_recurse ;
@@ -1171,7 +1221,12 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
11711221 break ;
11721222 case DT_REG :
11731223 case DT_LNK :
1174- break ;
1224+ switch (treat_file (dir , path , exclude , & dtype )) {
1225+ case 1 :
1226+ return path_ignored ;
1227+ default :
1228+ break ;
1229+ }
11751230 }
11761231 return path_handled ;
11771232}
0 commit comments