Skip to content

Commit 4bddd98

Browse files
tgummerergitster
authored andcommitted
split-index: don't write cache tree with null oid entries
In a96d3cc ("cache-tree: reject entries with null sha1", 2017-04-21) we made sure that broken cache entries do not get propagated to new trees. Part of that was making sure not to re-use an existing cache tree that includes a null oid. It did so by dropping the cache tree in 'do_write_index()' if one of the entries contains a null oid. In split index mode however, there are two invocations to 'do_write_index()', one for the shared index and one for the split index. The cache tree is only written once, to the split index. As we only loop through the elements that are effectively being written by the current invocation, that may not include the entry with a null oid in the split index (when it is already written to the shared index), where we write the cache tree. Therefore in split index mode we may still end up writing the cache tree, even though there is an entry with a null oid in the index. Fix this by checking for null oids in prepare_to_write_split_index, where we loop the entries of the shared index as well as the entries for the split index. This fixes t7009 with GIT_TEST_SPLIT_INDEX. Also add a new test that's more specifically showing the problem. Signed-off-by: Thomas Gummerer <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent a125a22 commit 4bddd98

File tree

4 files changed

+24
-2
lines changed

4 files changed

+24
-2
lines changed

cache.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,8 @@ struct index_state {
340340
struct split_index *split_index;
341341
struct cache_time timestamp;
342342
unsigned name_hash_initialized : 1,
343-
initialized : 1;
343+
initialized : 1,
344+
drop_cache_tree : 1;
344345
struct hashmap name_hash;
345346
struct hashmap dir_hash;
346347
unsigned char sha1[20];

read-cache.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2199,7 +2199,7 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile,
21992199
struct stat st;
22002200
struct ondisk_cache_entry_extended ondisk;
22012201
struct strbuf previous_name_buf = STRBUF_INIT, *previous_name;
2202-
int drop_cache_tree = 0;
2202+
int drop_cache_tree = istate->drop_cache_tree;
22032203

22042204
for (i = removed = extended = 0; i < entries; i++) {
22052205
if (cache[i]->ce_flags & CE_REMOVE)

split-index.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,8 @@ void prepare_to_write_split_index(struct index_state *istate)
238238
ALLOC_GROW(entries, nr_entries+1, nr_alloc);
239239
entries[nr_entries++] = ce;
240240
}
241+
if (is_null_oid(&ce->oid))
242+
istate->drop_cache_tree = 1;
241243
}
242244
}
243245

t/t1700-split-index.sh

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,4 +400,23 @@ done <<\EOF
400400
0642 -rw-r---w-
401401
EOF
402402

403+
test_expect_success 'writing split index with null sha1 does not write cache tree' '
404+
git config core.splitIndex true &&
405+
git config splitIndex.maxPercentChange 0 &&
406+
git commit -m "commit" &&
407+
{
408+
git ls-tree HEAD &&
409+
printf "160000 commit $_z40\\tbroken\\n"
410+
} >broken-tree &&
411+
echo "add broken entry" >msg &&
412+
413+
tree=$(git mktree <broken-tree) &&
414+
test_tick &&
415+
commit=$(git commit-tree $tree -p HEAD <msg) &&
416+
git update-ref HEAD "$commit" &&
417+
GIT_ALLOW_NULL_SHA1=1 git reset --hard &&
418+
(test-dump-cache-tree >cache-tree.out || true) &&
419+
test_line_count = 0 cache-tree.out
420+
'
421+
403422
test_done

0 commit comments

Comments
 (0)