diff options
Diffstat (limited to 'cache-tree.c')
| -rw-r--r-- | cache-tree.c | 42 | 
1 files changed, 32 insertions, 10 deletions
diff --git a/cache-tree.c b/cache-tree.c index 90919f9e34..79d168192d 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -440,8 +440,9 @@ static int update_one(struct cache_tree *it,  	} else if (dryrun) {  		hash_object_file(the_hash_algo, buffer.buf, buffer.len,  				 tree_type, &it->oid); -	} else if (write_object_file(buffer.buf, buffer.len, tree_type, -				     &it->oid)) { +	} else if (write_object_file_flags(buffer.buf, buffer.len, tree_type, +					   &it->oid, flags & WRITE_TREE_SILENT +					   ? HASH_SILENT : 0)) {  		strbuf_release(&buffer);  		return -1;  	} @@ -826,10 +827,17 @@ static void verify_one_sparse(struct repository *r,  		    path->buf);  } -static void verify_one(struct repository *r, -		       struct index_state *istate, -		       struct cache_tree *it, -		       struct strbuf *path) +/* + * Returns: + *  0 - Verification completed. + *  1 - Restart verification - a call to ensure_full_index() freed the cache + *      tree that is being verified and verification needs to be restarted from + *      the new toplevel cache tree. + */ +static int verify_one(struct repository *r, +		      struct index_state *istate, +		      struct cache_tree *it, +		      struct strbuf *path)  {  	int i, pos, len = path->len;  	struct strbuf tree_buf = STRBUF_INIT; @@ -837,21 +845,30 @@ static void verify_one(struct repository *r,  	for (i = 0; i < it->subtree_nr; i++) {  		strbuf_addf(path, "%s/", it->down[i]->name); -		verify_one(r, istate, it->down[i]->cache_tree, path); +		if (verify_one(r, istate, it->down[i]->cache_tree, path)) +			return 1;  		strbuf_setlen(path, len);  	}  	if (it->entry_count < 0 ||  	    /* no verification on tests (t7003) that replace trees */  	    lookup_replace_object(r, &it->oid) != &it->oid) -		return; +		return 0;  	if (path->len) { +		/* +		 * If the index is sparse and the cache tree is not +		 * index_name_pos() may trigger ensure_full_index() which will +		 * free the tree that is being verified. +		 */ +		int is_sparse = istate->sparse_index;  		pos = index_name_pos(istate, path->buf, path->len); +		if (is_sparse && !istate->sparse_index) +			return 1;  		if (pos >= 0) {  			verify_one_sparse(r, istate, it, path, pos); -			return; +			return 0;  		}  		pos = -pos - 1; @@ -899,6 +916,7 @@ static void verify_one(struct repository *r,  		    oid_to_hex(&new_oid), oid_to_hex(&it->oid));  	strbuf_setlen(path, len);  	strbuf_release(&tree_buf); +	return 0;  }  void cache_tree_verify(struct repository *r, struct index_state *istate) @@ -907,6 +925,10 @@ void cache_tree_verify(struct repository *r, struct index_state *istate)  	if (!istate->cache_tree)  		return; -	verify_one(r, istate, istate->cache_tree, &path); +	if (verify_one(r, istate, istate->cache_tree, &path)) { +		strbuf_reset(&path); +		if (verify_one(r, istate, istate->cache_tree, &path)) +			BUG("ensure_full_index() called twice while verifying cache tree"); +	}  	strbuf_release(&path);  }  | 
