From d2986d0f290a065fb8a534fabfff36c40d37ae97 Mon Sep 17 00:00:00 2001 From: Eric Wong Date: Wed, 25 May 2016 22:54:02 +0000 Subject: fast-import: invalidate pack_id references after loosening When loosening a pack, the current pack_id gets reused when checkpointing and the import does not terminate. This causes problems after checkpointing as the object table, branch, and tag lists still contains pre-checkpoint references to the recycled pack_id. Merely clearing the object_table as suggested by Jeff King in http://mid.gmane.org/20160517121330.GA7346@sigill.intra.peff.net is insufficient as the marks set still contains references to object entries. Wrong pack_id references branch and tags lists do not cause errors, but can lead to misleading crash reports and core dumps, so they are also invalidated. Signed-off-by: Eric Wong Signed-off-by: Junio C Hamano --- fast-import.c | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) (limited to 'fast-import.c') diff --git a/fast-import.c b/fast-import.c index 4fb464c1e..e415f517f 100644 --- a/fast-import.c +++ b/fast-import.c @@ -597,6 +597,33 @@ static struct object_entry *insert_object(unsigned char *sha1) return e; } +static void invalidate_pack_id(unsigned int id) +{ + unsigned int h; + unsigned long lu; + struct tag *t; + + for (h = 0; h < ARRAY_SIZE(object_table); h++) { + struct object_entry *e; + + for (e = object_table[h]; e; e = e->next) + if (e->pack_id == id) + e->pack_id = MAX_PACK_ID; + } + + for (lu = 0; lu < branch_table_sz; lu++) { + struct branch *b; + + for (b = branch_table[lu]; b; b = b->table_next_branch) + if (b->pack_id == id) + b->pack_id = MAX_PACK_ID; + } + + for (t = first_tag; t; t = t->next_tag) + if (t->pack_id == id) + t->pack_id = MAX_PACK_ID; +} + static unsigned int hc_str(const char *s, size_t len) { unsigned int r = 0; @@ -993,8 +1020,10 @@ static void end_packfile(void) cur_pack_sha1, pack_size); if (object_count <= unpack_limit) { - if (!loosen_small_pack(pack_data)) + if (!loosen_small_pack(pack_data)) { + invalidate_pack_id(pack_id); goto discard_pack; + } } close(pack_data->pack_fd); -- cgit v1.2.1