@@ -842,7 +842,8 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len)
842
842
843
843
static struct dir_entry * dir_add_name (struct dir_struct * dir , const char * pathname , int len )
844
844
{
845
- if (cache_name_exists (pathname , len , ignore_case ))
845
+ if (!(dir -> flags & DIR_SHOW_IGNORED ) &&
846
+ cache_name_exists (pathname , len , ignore_case ))
846
847
return NULL ;
847
848
848
849
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)
944
945
* traversal routine.
945
946
*
946
947
* 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
949
951
*
950
952
* Case 2: If we *already* have that directory name as a gitlink,
951
953
* 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)
959
961
* just a directory, unless "hide_empty_directories" is
960
962
* also true and the directory is empty, in which case
961
963
* 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.
962
967
* (b) if it looks like a git directory, and we don't have
963
968
* 'no_gitlinks' set we treat it as a gitlink, and show it
964
969
* as a directory.
@@ -971,12 +976,15 @@ enum directory_treatment {
971
976
};
972
977
973
978
static enum directory_treatment treat_directory (struct dir_struct * dir ,
974
- const char * dirname , int len ,
979
+ const char * dirname , int len , int exclude ,
975
980
const struct path_simplify * simplify )
976
981
{
977
982
/* The "len-1" is to strip the final '/' */
978
983
switch (directory_exists_in_index (dirname , len - 1 )) {
979
984
case index_directory :
985
+ if ((dir -> flags & DIR_SHOW_OTHER_DIRECTORIES ) && exclude )
986
+ break ;
987
+
980
988
return recurse_into_directory ;
981
989
982
990
case index_gitdir :
@@ -996,13 +1004,68 @@ static enum directory_treatment treat_directory(struct dir_struct *dir,
996
1004
}
997
1005
998
1006
/* 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 ))
1000
1024
return show_directory ;
1001
1025
if (!read_directory_recursive (dir , dirname , len , 1 , simplify ))
1002
1026
return ignore_directory ;
1003
1027
return show_directory ;
1004
1028
}
1005
1029
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
+
1006
1069
/*
1007
1070
* This is an inexact early pruning of any recursive directory
1008
1071
* 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,
1141
1204
if (dtype == DT_UNKNOWN )
1142
1205
dtype = get_dtype (de , path -> buf , path -> len );
1143
1206
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
-
1155
1207
switch (dtype ) {
1156
1208
default :
1157
1209
return path_ignored ;
1158
1210
case DT_DIR :
1159
1211
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 )) {
1161
1214
case show_directory :
1162
- if (exclude != !!(dir -> flags
1163
- & DIR_SHOW_IGNORED ))
1164
- return path_ignored ;
1165
1215
break ;
1166
1216
case recurse_into_directory :
1167
1217
return path_recurse ;
@@ -1171,7 +1221,12 @@ static enum path_treatment treat_one_path(struct dir_struct *dir,
1171
1221
break ;
1172
1222
case DT_REG :
1173
1223
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
+ }
1175
1230
}
1176
1231
return path_handled ;
1177
1232
}
0 commit comments