diff options
| author | Junio C Hamano <gitster@pobox.com> | 2024-09-12 11:47:23 -0700 |
|---|---|---|
| committer | Junio C Hamano <gitster@pobox.com> | 2024-09-12 11:47:23 -0700 |
| commit | 3bf057a0cd6a75125a5bd239372f9fc4fea6c338 (patch) | |
| tree | 67d0059da55bf1ed31e1b484c0ae8a9d52495de8 /builtin/pack-objects.c | |
| parent | 04595eb4079e33496124a132832d28aba4a94dfc (diff) | |
| parent | d3e7db2b8285e3ac3e9c28df51eab8237bf9c700 (diff) | |
Merge branch 'tb/multi-pack-reuse-fix'
A data corruption bug when multi-pack-index is used and the same
objects are stored in multiple packfiles has been corrected.
* tb/multi-pack-reuse-fix:
builtin/pack-objects.c: do not open-code `MAX_PACK_OBJECT_HEADER`
pack-bitmap.c: avoid repeated `pack_pos_to_offset()` during reuse
builtin/pack-objects.c: translate bit positions during pack-reuse
pack-bitmap: tag bitmapped packs with their corresponding MIDX
t/t5332-multi-pack-reuse.sh: verify pack generation with --strict
Diffstat (limited to 'builtin/pack-objects.c')
| -rw-r--r-- | builtin/pack-objects.c | 46 |
1 files changed, 37 insertions, 9 deletions
diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 778be80f56..c6e2852d3c 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1072,7 +1072,7 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile, fixup = find_reused_offset(offset) - find_reused_offset(base_offset); if (fixup) { - unsigned char ofs_header[10]; + unsigned char ofs_header[MAX_PACK_OBJECT_HEADER]; unsigned i, ofs_len; off_t ofs = offset - base_offset - fixup; @@ -1191,6 +1191,7 @@ static void write_reused_pack(struct bitmapped_pack *reuse_packfile, size_t pos = (i * BITS_IN_EWORD); for (offset = 0; offset < BITS_IN_EWORD; ++offset) { + uint32_t pack_pos; if ((word >> offset) == 0) break; @@ -1199,14 +1200,41 @@ static void write_reused_pack(struct bitmapped_pack *reuse_packfile, continue; if (pos + offset >= reuse_packfile->bitmap_pos + reuse_packfile->bitmap_nr) goto done; - /* - * Can use bit positions directly, even for MIDX - * bitmaps. See comment in try_partial_reuse() - * for why. - */ - write_reused_pack_one(reuse_packfile->p, - pos + offset - reuse_packfile->bitmap_pos, - f, pack_start, &w_curs); + + if (reuse_packfile->bitmap_pos) { + /* + * When doing multi-pack reuse on a + * non-preferred pack, translate bit positions + * from the MIDX pseudo-pack order back to their + * pack-relative positions before attempting + * reuse. + */ + struct multi_pack_index *m = reuse_packfile->from_midx; + uint32_t midx_pos; + off_t pack_ofs; + + if (!m) + BUG("non-zero bitmap position without MIDX"); + + midx_pos = pack_pos_to_midx(m, pos + offset); + pack_ofs = nth_midxed_offset(m, midx_pos); + + if (offset_to_pack_pos(reuse_packfile->p, + pack_ofs, &pack_pos) < 0) + BUG("could not find expected object at offset %"PRIuMAX" in pack %s", + (uintmax_t)pack_ofs, + pack_basename(reuse_packfile->p)); + } else { + /* + * Can use bit positions directly, even for MIDX + * bitmaps. See comment in try_partial_reuse() + * for why. + */ + pack_pos = pos + offset; + } + + write_reused_pack_one(reuse_packfile->p, pack_pos, f, + pack_start, &w_curs); display_progress(progress_state, ++written); } } |
