/* * Read a directory tree. We currently ignore anything but * directories, regular files and symlinks. That's because git * doesn't handle them at all yet. Maybe that will change some * day. * * Also, we ignore the name ".git" (even if it is not a directory). * That likely will not change. */ static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify) { DIR *fdir; int contents = 0; struct dirent *de; struct strbuf path = STRBUF_INIT; strbuf_add(&path, base, baselen); fdir = opendir(path.len ? path.buf : "."); if (!fdir) goto out; while ((de = readdir(fdir)) != NULL) { switch (treat_path(dir, de, &path, baselen, simplify)) { case path_recurse: contents += read_directory_recursive(dir, path.buf, path.len, 0, simplify); continue; case path_ignored: continue; case path_handled: break; } contents++; if (check_only) break; dir_add_name(dir, path.buf, path.len); } closedir(fdir); out: strbuf_release(&path); return contents; }
/* * Read a directory tree. We currently ignore anything but * directories, regular files and symlinks. That's because git * doesn't handle them at all yet. Maybe that will change some * day. * * Also, we ignore the name ".git" (even if it is not a directory). * That likely will not change. */ static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify) { DIR *fdir = opendir(*base ? base : "."); int contents = 0; struct dirent *de; char path[PATH_MAX + 1]; if (!fdir) return 0; memcpy(path, base, baselen); while ((de = readdir(fdir)) != NULL) { int len; switch (treat_path(dir, de, path, sizeof(path), baselen, simplify, &len)) { case path_recurse: contents += read_directory_recursive(dir, path, len, 0, simplify); continue; case path_ignored: continue; case path_handled: break; } contents++; if (check_only) goto exit_early; else dir_add_name(dir, path, len); } exit_early: closedir(fdir); return contents; }
/* * Read a directory tree. We currently ignore anything but * directories, regular files and symlinks. That's because git * doesn't handle them at all yet. Maybe that will change some * day. * * Also, we ignore the name ".git" (even if it is not a directory). * That likely will not change. * * Returns the most significant path_treatment value encountered in the scan. */ static enum path_treatment read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify) { DIR *fdir; enum path_treatment state, subdir_state, dir_state = path_none; struct dirent *de; struct strbuf path = STRBUF_INIT; strbuf_add(&path, base, baselen); fdir = opendir(path.len ? path.buf : "."); if (!fdir) goto out; while ((de = readdir(fdir)) != NULL) { /* check how the file or directory should be treated */ state = treat_path(dir, de, &path, baselen, simplify); if (state > dir_state) dir_state = state; /* recurse into subdir if instructed by treat_path */ if (state == path_recurse) { subdir_state = read_directory_recursive(dir, path.buf, path.len, check_only, simplify); if (subdir_state > dir_state) dir_state = subdir_state; } if (check_only) { /* abort early if maximum state has been reached */ if (dir_state == path_untracked) break; /* skip the dir_add_* part */ continue; } /* add the path to the appropriate result list */ switch (state) { case path_excluded: if (dir->flags & DIR_SHOW_IGNORED) dir_add_name(dir, path.buf, path.len); else if ((dir->flags & DIR_SHOW_IGNORED_TOO) || ((dir->flags & DIR_COLLECT_IGNORED) && exclude_matches_pathspec(path.buf, path.len, simplify))) dir_add_ignored(dir, path.buf, path.len); break; case path_untracked: if (!(dir->flags & DIR_SHOW_IGNORED)) dir_add_name(dir, path.buf, path.len); break; default: break; } } closedir(fdir); out: strbuf_release(&path); return dir_state; }