diff options
author | Eric Wong <e@80x24.org> | 2016-05-25 22:54:02 +0000 |
---|---|---|
committer | Junio C Hamano <gitster@pobox.com> | 2016-05-29 17:58:34 -0700 |
commit | d2986d0f290a065fb8a534fabfff36c40d37ae97 (patch) | |
tree | aa72980b793fbce0b54da1defdfe6c41acd28e1e /fast-import.c | |
parent | d9545c7f465ed103df44cd93caddfdd265757779 (diff) | |
download | git-d2986d0f290a065fb8a534fabfff36c40d37ae97.tar.gz |
fast-import: invalidate pack_id references after looseningew/fast-import-unpack-limit
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 <e@80x24.org>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'fast-import.c')
-rw-r--r-- | fast-import.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/fast-import.c b/fast-import.c index 4fb464c1ef..e415f517f8 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); |