/* * 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; }
static int read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, struct index_state *index, const char *worktree, IgnoreFunc ignore_func, void *data) { char *realpath = g_build_path (PATH_SEPERATOR, worktree, base, NULL); GDir *fdir = g_dir_open (realpath, 0, NULL); const char *dname; char *nfc_dname; int contents = 0; int dtype; if (fdir) { char path[SEAF_PATH_MAX + 1]; memcpy(path, base, baselen); while ((dname = g_dir_read_name(fdir)) != NULL) { int len = 0; #ifdef __APPLE__ nfc_dname = g_utf8_normalize (dname, -1, G_NORMALIZE_NFC); #else nfc_dname = g_strdup(dname); #endif if (is_dot_or_dotdot(nfc_dname)) { g_free (nfc_dname); continue; } if (ignore_func (realpath, nfc_dname, data)) { g_free (nfc_dname); continue; } dtype = get_dtype(nfc_dname, realpath); switch (dtype) { case DT_REG: len = strlen(nfc_dname); memcpy(path + baselen, nfc_dname, len + 1); len = strlen(path); break; case DT_DIR: len = strlen(nfc_dname); memcpy(path + baselen, nfc_dname, len + 1); memcpy(path + baselen + len, "/", 2); len = strlen(path); read_directory_recursive(dir, path, len, 0, index, worktree, ignore_func, data); g_free (nfc_dname); continue; default: /* DT_UNKNOWN */ len = 0; break; } if(len > 0) dir_add_name(dir, path, len, index); g_free (nfc_dname); } g_dir_close(fdir); } g_free(realpath); 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; }
/* * 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 *path, const char *base, int baselen, int check_only, const struct path_simplify *simplify) { DIR *fdir = opendir(path); int contents = 0; if (fdir) { struct dirent *de; char fullname[PATH_MAX + 1]; memcpy(fullname, base, baselen); while ((de = readdir(fdir)) != NULL) { int len, dtype; int exclude; if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git")) continue; len = strlen(de->d_name); /* Ignore overly long pathnames! */ if (len + baselen + 8 > sizeof(fullname)) continue; memcpy(fullname + baselen, de->d_name, len+1); if (simplify_away(fullname, baselen + len, simplify)) continue; dtype = DTYPE(de); exclude = excluded(dir, fullname, &dtype); if (exclude && (dir->flags & DIR_COLLECT_IGNORED) && in_pathspec(fullname, baselen + len, simplify)) dir_add_ignored(dir, fullname, baselen + len); /* * Excluded? If we don't explicitly want to show * ignored files, ignore it */ if (exclude && !(dir->flags & DIR_SHOW_IGNORED)) continue; if (dtype == DT_UNKNOWN) dtype = get_dtype(de, fullname); /* * Do we want to see just the ignored files? * We still need to recurse into directories, * even if we don't ignore them, since the * directory may contain files that we do.. */ if (!exclude && (dir->flags & DIR_SHOW_IGNORED)) { if (dtype != DT_DIR) continue; } switch (dtype) { default: continue; case DT_DIR: memcpy(fullname + baselen + len, "/", 2); len++; switch (treat_directory(dir, fullname, baselen + len, simplify)) { case show_directory: if (exclude != !!(dir->flags & DIR_SHOW_IGNORED)) continue; break; case recurse_into_directory: contents += read_directory_recursive(dir, fullname, fullname, baselen + len, 0, simplify); continue; case ignore_directory: continue; } break; case DT_REG: case DT_LNK: break; } contents++; if (check_only) goto exit_early; else dir_add_name(dir, fullname, baselen + len); } exit_early: closedir(fdir); } return contents; }