static enum directory_treatment treat_directory(struct dir_struct *dir, const char *dirname, int len, const struct path_simplify *simplify) { /* The "len-1" is to strip the final '/' */ switch (directory_exists_in_index(dirname, len-1)) { case index_directory: return recurse_into_directory; case index_gitdir: if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES) return ignore_directory; return show_directory; case index_nonexistent: if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES) break; if (!(dir->flags & DIR_NO_GITLINKS)) { unsigned char sha1[20]; if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0) return show_directory; } return recurse_into_directory; } /* This is the "show_other_directories" case */ if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES)) return show_directory; if (!read_directory_recursive(dir, dirname, len, 1, simplify)) return ignore_directory; return show_directory; }
static enum path_treatment treat_one_path(struct dir_struct *dir, struct strbuf *path, const struct path_simplify *simplify, int dtype, struct dirent *de) { int exclude; int has_path_in_index = !!cache_file_exists(path->buf, path->len, ignore_case); if (dtype == DT_UNKNOWN) dtype = get_dtype(de, path->buf, path->len); /* Always exclude indexed files */ if (dtype != DT_DIR && has_path_in_index) return path_none; /* * When we are looking at a directory P in the working tree, * there are three cases: * * (1) P exists in the index. Everything inside the directory P in * the working tree needs to go when P is checked out from the * index. * * (2) P does not exist in the index, but there is P/Q in the index. * We know P will stay a directory when we check out the contents * of the index, but we do not know yet if there is a directory * P/Q in the working tree to be killed, so we need to recurse. * * (3) P does not exist in the index, and there is no P/Q in the index * to require P to be a directory, either. Only in this case, we * know that everything inside P will not be killed without * recursing. */ if ((dir->flags & DIR_COLLECT_KILLED_ONLY) && (dtype == DT_DIR) && !has_path_in_index && (directory_exists_in_index(path->buf, path->len) == index_nonexistent)) return path_none; exclude = is_excluded(dir, path->buf, &dtype); /* * Excluded? If we don't explicitly want to show * ignored files, ignore it */ if (exclude && !(dir->flags & (DIR_SHOW_IGNORED|DIR_SHOW_IGNORED_TOO))) return path_excluded; switch (dtype) { default: return path_none; case DT_DIR: strbuf_addch(path, '/'); return treat_directory(dir, path->buf, path->len, exclude, simplify); case DT_REG: case DT_LNK: return exclude ? path_excluded : path_untracked; } }