diff options
Diffstat (limited to 'dir.c')
-rw-r--r-- | dir.c | 88 |
1 files changed, 46 insertions, 42 deletions
@@ -502,8 +502,7 @@ int submodule_path_match(const struct index_state *istate, } int report_path_error(const char *ps_matched, - const struct pathspec *pathspec, - const char *prefix) + const struct pathspec *pathspec) { /* * Make sure all pathspec matched; otherwise it is an error. @@ -702,7 +701,7 @@ static struct untracked_cache_dir *lookup_untracked(struct untracked_cache *uc, first = 0; last = dir->dirs_nr; while (last > first) { - int cmp, next = (last + first) >> 1; + int cmp, next = first + ((last - first) >> 1); d = dir->dirs[next]; cmp = strncmp(name, d->name, len); if (!cmp && strlen(d->name) > len) @@ -1467,9 +1466,11 @@ static enum path_treatment treat_directory(struct dir_struct *dir, return path_none; } if (!(dir->flags & DIR_NO_GITLINKS)) { - struct object_id oid; - if (resolve_gitlink_ref(dirname, "HEAD", &oid) == 0) + struct strbuf sb = STRBUF_INIT; + strbuf_addstr(&sb, dirname); + if (is_nonbare_repository_dir(&sb)) return exclude ? path_excluded : path_untracked; + strbuf_release(&sb); } return path_recurse; } @@ -2315,6 +2316,14 @@ int file_exists(const char *f) return lstat(f, &sb) == 0; } +int repo_file_exists(struct repository *repo, const char *path) +{ + if (repo != the_repository) + BUG("do not know how to check file existence in arbitrary repo"); + + return file_exists(path); +} + static int cmp_icase(char a, char b) { if (a == b) @@ -2545,13 +2554,9 @@ struct ondisk_untracked_cache { struct stat_data info_exclude_stat; struct stat_data excludes_file_stat; uint32_t dir_flags; - unsigned char info_exclude_sha1[20]; - unsigned char excludes_file_sha1[20]; - char exclude_per_dir[FLEX_ARRAY]; }; #define ouc_offset(x) offsetof(struct ondisk_untracked_cache, x) -#define ouc_size(len) (ouc_offset(exclude_per_dir) + len + 1) struct write_data { int index; /* number of written untracked_cache_dir */ @@ -2634,20 +2639,21 @@ void write_untracked_extension(struct strbuf *out, struct untracked_cache *untra struct write_data wd; unsigned char varbuf[16]; int varint_len; - size_t len = strlen(untracked->exclude_per_dir); + const unsigned hashsz = the_hash_algo->rawsz; - FLEX_ALLOC_MEM(ouc, exclude_per_dir, untracked->exclude_per_dir, len); + ouc = xcalloc(1, sizeof(*ouc)); 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); - hashcpy(ouc->info_exclude_sha1, untracked->ss_info_exclude.oid.hash); - hashcpy(ouc->excludes_file_sha1, untracked->ss_excludes_file.oid.hash); ouc->dir_flags = htonl(untracked->dir_flags); varint_len = encode_varint(untracked->ident.len, varbuf); strbuf_add(out, varbuf, varint_len); strbuf_addbuf(out, &untracked->ident); - strbuf_add(out, ouc, ouc_size(len)); + strbuf_add(out, ouc, sizeof(*ouc)); + strbuf_add(out, untracked->ss_info_exclude.oid.hash, hashsz); + strbuf_add(out, untracked->ss_excludes_file.oid.hash, hashsz); + strbuf_add(out, untracked->exclude_per_dir, strlen(untracked->exclude_per_dir) + 1); FREE_AND_NULL(ouc); if (!untracked->root) { @@ -2732,54 +2738,49 @@ static int read_one_dir(struct untracked_cache_dir **untracked_, struct read_data *rd) { struct untracked_cache_dir ud, *untracked; - const unsigned char *next, *data = rd->data, *end = rd->end; + const unsigned char *data = rd->data, *end = rd->end; + const unsigned char *eos; unsigned int value; - int i, len; + int i; memset(&ud, 0, sizeof(ud)); - next = data; - value = decode_varint(&next); - if (next > end) + value = decode_varint(&data); + if (data > end) return -1; ud.recurse = 1; ud.untracked_alloc = value; ud.untracked_nr = value; if (ud.untracked_nr) ALLOC_ARRAY(ud.untracked, ud.untracked_nr); - data = next; - next = data; - ud.dirs_alloc = ud.dirs_nr = decode_varint(&next); - if (next > end) + ud.dirs_alloc = ud.dirs_nr = decode_varint(&data); + if (data > end) return -1; ALLOC_ARRAY(ud.dirs, ud.dirs_nr); - data = next; - len = strlen((const char *)data); - next = data + len + 1; - if (next > rd->end) + eos = memchr(data, '\0', end - data); + if (!eos || eos == end) return -1; - *untracked_ = untracked = xmalloc(st_add(sizeof(*untracked), len)); + + *untracked_ = untracked = xmalloc(st_add3(sizeof(*untracked), eos - data, 1)); memcpy(untracked, &ud, sizeof(ud)); - memcpy(untracked->name, data, len + 1); - data = next; + memcpy(untracked->name, data, eos - data + 1); + data = eos + 1; for (i = 0; i < untracked->untracked_nr; i++) { - len = strlen((const char *)data); - next = data + len + 1; - if (next > rd->end) + eos = memchr(data, '\0', end - data); + if (!eos || eos == end) return -1; - untracked->untracked[i] = xstrdup((const char*)data); - data = next; + untracked->untracked[i] = xmemdupz(data, eos - data); + data = eos + 1; } rd->ucd[rd->index++] = untracked; rd->data = data; for (i = 0; i < untracked->dirs_nr; i++) { - len = read_one_dir(untracked->dirs + i, rd); - if (len < 0) + if (read_one_dir(untracked->dirs + i, rd) < 0) return -1; } return 0; @@ -2834,6 +2835,9 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long int ident_len; ssize_t len; const char *exclude_per_dir; + const unsigned hashsz = the_hash_algo->rawsz; + const unsigned offset = sizeof(struct ondisk_untracked_cache); + const unsigned exclude_per_dir_offset = offset + 2 * hashsz; if (sz <= 1 || end[-1] != '\0') return NULL; @@ -2845,7 +2849,7 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long ident = (const char *)next; next += ident_len; - if (next + ouc_size(0) > end) + if (next + exclude_per_dir_offset + 1 > end) return NULL; uc = xcalloc(1, sizeof(*uc)); @@ -2853,15 +2857,15 @@ struct untracked_cache *read_untracked_extension(const void *data, unsigned long strbuf_add(&uc->ident, ident, ident_len); load_oid_stat(&uc->ss_info_exclude, next + ouc_offset(info_exclude_stat), - next + ouc_offset(info_exclude_sha1)); + next + offset); load_oid_stat(&uc->ss_excludes_file, next + ouc_offset(excludes_file_stat), - next + ouc_offset(excludes_file_sha1)); + next + offset + hashsz); uc->dir_flags = get_be32(next + ouc_offset(dir_flags)); - exclude_per_dir = (const char *)next + ouc_offset(exclude_per_dir); + exclude_per_dir = (const char *)next + exclude_per_dir_offset; uc->exclude_per_dir = xstrdup(exclude_per_dir); /* NUL after exclude_per_dir is covered by sizeof(*ouc) */ - next += ouc_size(strlen(exclude_per_dir)); + next += exclude_per_dir_offset + strlen(exclude_per_dir) + 1; if (next >= end) goto done2; |