diff options
Diffstat (limited to 'read-cache.c')
| -rw-r--r-- | read-cache.c | 78 |
1 files changed, 47 insertions, 31 deletions
diff --git a/read-cache.c b/read-cache.c index 383ec6d366..342723e8d6 100644 --- a/read-cache.c +++ b/read-cache.c @@ -488,11 +488,11 @@ int ie_modified(struct index_state *istate, return 0; } -int base_name_compare(const char *name1, int len1, int mode1, - const char *name2, int len2, int mode2) +int base_name_compare(const char *name1, size_t len1, int mode1, + const char *name2, size_t len2, int mode2) { unsigned char c1, c2; - int len = len1 < len2 ? len1 : len2; + size_t len = len1 < len2 ? len1 : len2; int cmp; cmp = memcmp(name1, name2, len); @@ -517,11 +517,12 @@ int base_name_compare(const char *name1, int len1, int mode1, * This is used by routines that want to traverse the git namespace * but then handle conflicting entries together when possible. */ -int df_name_compare(const char *name1, int len1, int mode1, - const char *name2, int len2, int mode2) +int df_name_compare(const char *name1, size_t len1, int mode1, + const char *name2, size_t len2, int mode2) { - int len = len1 < len2 ? len1 : len2, cmp; unsigned char c1, c2; + size_t len = len1 < len2 ? len1 : len2; + int cmp; cmp = memcmp(name1, name2, len); if (cmp) @@ -1783,6 +1784,8 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size) git_hash_ctx c; unsigned char hash[GIT_MAX_RAWSZ]; int hdr_version; + unsigned char *start, *end; + struct object_id oid; if (hdr->hdr_signature != htonl(CACHE_SIGNATURE)) return error(_("bad signature 0x%08x"), hdr->hdr_signature); @@ -1793,10 +1796,16 @@ static int verify_hdr(const struct cache_header *hdr, unsigned long size) if (!verify_index_checksum) return 0; + end = (unsigned char *)hdr + size; + start = end - the_hash_algo->rawsz; + oidread(&oid, start); + if (oideq(&oid, null_oid())) + return 0; + the_hash_algo->init_fn(&c); the_hash_algo->update_fn(&c, hdr, size - the_hash_algo->rawsz); the_hash_algo->final_fn(hash, &c); - if (!hasheq(hash, (unsigned char *)hdr + size - the_hash_algo->rawsz)) + if (!hasheq(hash, start)) return error(_("bad index file sha1 signature")); return 0; } @@ -2258,12 +2267,10 @@ static void set_new_index_sparsity(struct index_state *istate) * If the index's repo exists, mark it sparse according to * repo settings. */ - if (istate->repo) { - prepare_repo_settings(istate->repo); - if (!istate->repo->settings.command_requires_full_index && - is_sparse_index_allowed(istate, 0)) - istate->sparse_index = 1; - } + prepare_repo_settings(istate->repo); + if (!istate->repo->settings.command_requires_full_index && + is_sparse_index_allowed(istate, 0)) + istate->sparse_index = 1; } /* remember to discard_cache() before reading a different cache! */ @@ -2288,8 +2295,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) fd = open(path, O_RDONLY); if (fd < 0) { if (!must_exist && errno == ENOENT) { - if (!istate->repo) - istate->repo = the_repository; set_new_index_sparsity(istate); return 0; } @@ -2391,9 +2396,6 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) trace2_data_intmax("index", the_repository, "read/cache_nr", istate->cache_nr); - if (!istate->repo) - istate->repo = the_repository; - /* * If the command explicitly requires a full index, force it * to be full. Otherwise, correct the sparsity based on repository @@ -2456,9 +2458,10 @@ int read_index_from(struct index_state *istate, const char *path, trace_performance_enter(); if (split_index->base) - discard_index(split_index->base); + release_index(split_index->base); else - CALLOC_ARRAY(split_index->base, 1); + ALLOC_ARRAY(split_index->base, 1); + index_state_init(split_index->base, istate->repo); base_oid_hex = oid_to_hex(&split_index->base_oid); base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex); @@ -2497,7 +2500,13 @@ int is_index_unborn(struct index_state *istate) return (!istate->cache_nr && !istate->timestamp.sec); } -void discard_index(struct index_state *istate) +void index_state_init(struct index_state *istate, struct repository *r) +{ + struct index_state blank = INDEX_STATE_INIT(r); + memcpy(istate, &blank, sizeof(*istate)); +} + +void release_index(struct index_state *istate) { /* * Cache entries in istate->cache[] should have been allocated @@ -2509,20 +2518,17 @@ void discard_index(struct index_state *istate) validate_cache_entries(istate); resolve_undo_clear_index(istate); - istate->cache_nr = 0; - istate->cache_changed = 0; - istate->timestamp.sec = 0; - istate->timestamp.nsec = 0; free_name_hash(istate); cache_tree_free(&(istate->cache_tree)); - istate->initialized = 0; - istate->fsmonitor_has_run_once = 0; - FREE_AND_NULL(istate->fsmonitor_last_update); - FREE_AND_NULL(istate->cache); - istate->cache_alloc = 0; + free(istate->fsmonitor_last_update); + free(istate->cache); discard_split_index(istate); free_untracked_cache(istate->untracked); - istate->untracked = NULL; + + if (istate->sparse_checkout_patterns) { + clear_pattern_list(istate->sparse_checkout_patterns); + FREE_AND_NULL(istate->sparse_checkout_patterns); + } if (istate->ce_mem_pool) { mem_pool_discard(istate->ce_mem_pool, should_validate_cache_entries()); @@ -2530,6 +2536,12 @@ void discard_index(struct index_state *istate) } } +void discard_index(struct index_state *istate) +{ + release_index(istate); + index_state_init(istate, istate->repo); +} + /* * Validate the cache entries of this index. * All cache entries associated with this index @@ -2881,9 +2893,13 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, int ieot_entries = 1; struct index_entry_offset_table *ieot = NULL; int nr, nr_threads; + struct repository *r = istate->repo; f = hashfd(tempfile->fd, tempfile->filename.buf); + prepare_repo_settings(r); + f->skip_hash = r->settings.index_skip_hash; + for (i = removed = extended = 0; i < entries; i++) { if (cache[i]->ce_flags & CE_REMOVE) removed++; |
