aboutsummaryrefslogtreecommitdiffstats
path: root/read-cache.c
diff options
context:
space:
mode:
Diffstat (limited to 'read-cache.c')
-rw-r--r--read-cache.c78
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++;