static void show_files(struct dir_struct *dir, const char *prefix) { int i; /* For cached/deleted files we don't need to even do the readdir */ if (show_others || show_killed) { const char *path = ".", *base = ""; int baselen = prefix_len; if (baselen) path = base = prefix; read_directory(dir, path, base, baselen, pathspec); if (show_others) show_other_files(dir); if (show_killed) show_killed_files(dir); } if (show_cached | show_stage) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; int dtype = ce_to_dtype(ce); if (excluded(dir, ce->name, &dtype) != dir->show_ignored) continue; if (show_unmerged && !ce_stage(ce)) continue; if (ce->ce_flags & CE_UPDATE) continue; show_ce_entry(ce_stage(ce) ? tag_unmerged : tag_cached, ce); } } if (show_deleted | show_modified) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; struct stat st; int err; int dtype = ce_to_dtype(ce); if (excluded(dir, ce->name, &dtype) != dir->show_ignored) continue; if (ce->ce_flags & CE_UPDATE) continue; err = lstat(ce->name, &st); if (show_deleted && err) show_ce_entry(tag_removed, ce); if (show_modified && ce_modified(ce, &st, 0)) show_ce_entry(tag_modified, ce); } } }
static void show_files(struct dir_struct *dir, const char *prefix) { int i; /* For cached/deleted files we don't need to even do the readdir */ if (show_others || show_killed) { fill_directory(dir, pathspec); if (show_others) show_other_files(dir); if (show_killed) show_killed_files(dir); } if (show_cached | show_stage) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; int dtype = ce_to_dtype(ce); if (dir->flags & DIR_SHOW_IGNORED && !excluded(dir, ce->name, &dtype)) continue; if (show_unmerged && !ce_stage(ce)) continue; if (ce->ce_flags & CE_UPDATE) continue; show_ce_entry(ce_stage(ce) ? tag_unmerged : (ce_skip_worktree(ce) ? tag_skip_worktree : tag_cached), ce); } } if (show_deleted | show_modified) { for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; struct stat st; int err; int dtype = ce_to_dtype(ce); if (dir->flags & DIR_SHOW_IGNORED && !excluded(dir, ce->name, &dtype)) continue; if (ce->ce_flags & CE_UPDATE) continue; if (ce_skip_worktree(ce)) continue; err = lstat(ce->name, &st); if (show_deleted && err) show_ce_entry(tag_removed, ce); if (show_modified && ce_modified(ce, &st, 0)) show_ce_entry(tag_modified, ce); } } }
/* * We do not want to remove or overwrite a working tree file that * is not tracked, unless it is ignored. */ static int verify_absent_1(const struct cache_entry *ce, enum unpack_trees_error_types error_type, struct unpack_trees_options *o) { int len; struct stat st; if (o->index_only || o->reset || !o->update) return 0; len = check_leading_path(ce->name, ce_namelen(ce)); if (!len) return 0; else if (len > 0) { char path[PATH_MAX + 1]; memcpy(path, ce->name, len); path[len] = 0; if (lstat(path, &st)) return error("cannot stat '%s': %s", path, strerror(errno)); return check_ok_to_remove(path, len, DT_UNKNOWN, NULL, &st, error_type, o); } else if (lstat(ce->name, &st)) { if (errno != ENOENT) return error("cannot stat '%s': %s", ce->name, strerror(errno)); return 0; } else { return check_ok_to_remove(ce->name, ce_namelen(ce), ce_to_dtype(ce), ce, &st, error_type, o); } }
/* * Traverse the index, find every entry that matches according to * o->el. Do "ce_flags &= ~clear_mask" on those entries. Return the * number of traversed entries. * * If select_mask is non-zero, only entries whose ce_flags has on of * those bits enabled are traversed. * * cache : pointer to an index entry * prefix_len : an offset to its path * * The current path ("prefix") including the trailing '/' is * cache[0]->name[0..(prefix_len-1)] * Top level path has prefix_len zero. */ static int clear_ce_flags_1(struct cache_entry **cache, int nr, struct strbuf *prefix, int select_mask, int clear_mask, struct exclude_list *el, int defval) { struct cache_entry **cache_end = cache + nr; /* * Process all entries that have the given prefix and meet * select_mask condition */ while(cache != cache_end) { struct cache_entry *ce = *cache; const char *name, *slash; int len, dtype, ret; if (select_mask && !(ce->ce_flags & select_mask)) { cache++; continue; } if (prefix->len && strncmp(ce->name, prefix->buf, prefix->len)) break; name = ce->name + prefix->len; slash = strchr(name, '/'); /* If it's a directory, try whole directory match first */ if (slash) { int processed; len = slash - name; strbuf_add(prefix, name, len); processed = clear_ce_flags_dir(cache, cache_end - cache, prefix, prefix->buf + prefix->len - len, select_mask, clear_mask, el, defval); /* clear_c_f_dir eats a whole dir already? */ if (processed) { cache += processed; strbuf_setlen(prefix, prefix->len - len); continue; } strbuf_addch(prefix, '/'); cache += clear_ce_flags_1(cache, cache_end - cache, prefix, select_mask, clear_mask, el, defval); strbuf_setlen(prefix, prefix->len - len - 1); continue; } /* Non-directory */ dtype = ce_to_dtype(ce); ret = is_excluded_from_list(ce->name, ce_namelen(ce), name, &dtype, el); if (ret < 0) ret = defval; if (ret > 0) ce->ce_flags &= ~clear_mask; cache++; } return nr - (cache_end - cache); }