diff options
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 63 |
1 files changed, 43 insertions, 20 deletions
@@ -817,8 +817,8 @@ static void add_pattern_to_hashsets(struct pattern_list *pl, struct path_pattern clear_hashmaps: warning(_("disabling cone pattern matching")); - hashmap_free_entries(&pl->parent_hashmap, struct pattern_entry, ent); - hashmap_free_entries(&pl->recursive_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->parent_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->recursive_hashmap, struct pattern_entry, ent); pl->use_cone_patterns = 0; } @@ -921,8 +921,8 @@ void clear_pattern_list(struct pattern_list *pl) free(pl->patterns[i]); free(pl->patterns); free(pl->filebuf); - hashmap_free_entries(&pl->recursive_hashmap, struct pattern_entry, ent); - hashmap_free_entries(&pl->parent_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->recursive_hashmap, struct pattern_entry, ent); + hashmap_clear_and_free(&pl->parent_hashmap, struct pattern_entry, ent); memset(pl, 0, sizeof(*pl)); } @@ -1035,18 +1035,21 @@ static int add_patterns_from_buffer(char *buf, size_t size, const char *base, int baselen, struct pattern_list *pl); +/* Flags for add_patterns() */ +#define PATTERN_NOFOLLOW (1<<0) + /* * Given a file with name "fname", read it (either from disk, or from * an index if 'istate' is non-null), parse it and store the * exclude rules in "pl". * - * If "ss" is not NULL, compute SHA-1 of the exclude file and fill + * If "oid_stat" is not NULL, compute oid of the exclude file and fill * stat data from disk (only valid if add_patterns returns zero). If - * ss_valid is non-zero, "ss" must contain good value as input. + * oid_stat.valid is non-zero, "oid_stat" must contain good value as input. */ static int add_patterns(const char *fname, const char *base, int baselen, struct pattern_list *pl, struct index_state *istate, - struct oid_stat *oid_stat) + unsigned flags, struct oid_stat *oid_stat) { struct stat st; int r; @@ -1054,7 +1057,11 @@ static int add_patterns(const char *fname, const char *base, int baselen, size_t size = 0; char *buf; - fd = open(fname, O_RDONLY); + if (flags & PATTERN_NOFOLLOW) + fd = open_nofollow(fname, O_RDONLY); + else + fd = open(fname, O_RDONLY); + if (fd < 0 || fstat(fd, &st) < 0) { if (fd < 0) warn_on_fopen_errors(fname); @@ -1090,7 +1097,7 @@ static int add_patterns(const char *fname, const char *base, int baselen, int pos; if (oid_stat->valid && !match_stat_data_racy(istate, &oid_stat->stat, &st)) - ; /* no content change, ss->sha1 still good */ + ; /* no content change, oid_stat->oid still good */ else if (istate && (pos = index_name_pos(istate, fname, strlen(fname))) >= 0 && !ce_stage(istate->cache[pos]) && @@ -1143,9 +1150,10 @@ static int add_patterns_from_buffer(char *buf, size_t size, int add_patterns_from_file_to_list(const char *fname, const char *base, int baselen, struct pattern_list *pl, - struct index_state *istate) + struct index_state *istate, + unsigned flags) { - return add_patterns(fname, base, baselen, pl, istate, NULL); + return add_patterns(fname, base, baselen, pl, istate, flags, NULL); } int add_patterns_from_blob_to_list( @@ -1194,7 +1202,7 @@ static void add_patterns_from_file_1(struct dir_struct *dir, const char *fname, if (!dir->untracked) dir->unmanaged_exclude_files++; pl = add_pattern_list(dir, EXC_FILE, fname); - if (add_patterns(fname, "", 0, pl, NULL, oid_stat) < 0) + if (add_patterns(fname, "", 0, pl, NULL, 0, oid_stat) < 0) die(_("cannot use %s as an exclude file"), fname); } @@ -1488,7 +1496,7 @@ static void prep_exclude(struct dir_struct *dir, const char *cp; struct oid_stat oid_stat; - stk = xcalloc(1, sizeof(*stk)); + CALLOC_ARRAY(stk, 1); if (current < 0) { cp = base; current = 0; @@ -1558,6 +1566,7 @@ static void prep_exclude(struct dir_struct *dir, strbuf_addstr(&sb, dir->exclude_per_dir); pl->src = strbuf_detach(&sb, NULL); add_patterns(pl->src, pl->src, stk->baselen, pl, istate, + PATTERN_NOFOLLOW, untracked ? &oid_stat : NULL); } /* @@ -2730,11 +2739,8 @@ static struct untracked_cache_dir *validate_untracked_cache(struct dir_struct *d return NULL; } - if (!dir->untracked->root) { - const int len = sizeof(*dir->untracked->root); - dir->untracked->root = xmalloc(len); - memset(dir->untracked->root, 0, len); - } + if (!dir->untracked->root) + FLEX_ALLOC_STR(dir->untracked->root, name, ""); /* Validate $GIT_DIR/info/exclude and core.excludesfile */ root = dir->untracked->root; @@ -2998,6 +3004,23 @@ void setup_standard_excludes(struct dir_struct *dir) } } +char *get_sparse_checkout_filename(void) +{ + return git_pathdup("info/sparse-checkout"); +} + +int get_sparse_checkout_patterns(struct pattern_list *pl) +{ + int res; + char *sparse_filename = get_sparse_checkout_filename(); + + pl->use_cone_patterns = core_sparse_checkout_cone; + res = add_patterns_from_file_to_list(sparse_filename, "", 0, pl, NULL, 0); + + free(sparse_filename); + return res; +} + int remove_path(const char *name) { char *slash; @@ -3148,7 +3171,7 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra int varint_len; const unsigned hashsz = the_hash_algo->rawsz; - ouc = xcalloc(1, sizeof(*ouc)); + CALLOC_ARRAY(ouc, 1); stat_data_to_disk(&ouc->info_exclude_stat, &untracked->ss_info_exclude.stat); stat_data_to_disk(&ouc->excludes_file_stat, &untracked->ss_excludes_file.stat); ouc->dir_flags = htonl(untracked->dir_flags); @@ -3359,7 +3382,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long if (next + exclude_per_dir_offset + 1 > end) return NULL; - uc = xcalloc(1, sizeof(*uc)); + CALLOC_ARRAY(uc, 1); strbuf_init(&uc->ident, ident_len); strbuf_add(&uc->ident, ident, ident_len); load_oid_stat(&uc->ss_info_exclude, |