Skip to content

Commit d1d701e

Browse files
ttaylorrgitster
authored andcommitted
pack-objects: keep track of pack_start for each reuse pack
When reusing objects from a pack, we keep track of a set of one or more `reused_chunk`s, corresponding to sections of one or more object(s) from a source pack that we are reusing. Each chunk contains two pieces of information: - the offset of the first object in the source pack (relative to the beginning of the source pack) - the difference between that offset, and the corresponding offset in the pack we're generating The purpose of keeping track of these is so that we can patch an OFS_DELTAs that cross over a section of the reuse pack that we didn't take. For instance, consider a hypothetical pack as shown below: (chunk #2) __________... / / +--------+---------+-------------------+---------+ ... | <base> | <other> | (unused) | <delta> | ... +--------+---------+-------------------+---------+ \ / \______________/ (chunk #1) Suppose that we are sending objects "base", "other", and "delta", and that the "delta" object is stored as an OFS_DELTA, and that its base is "base". If we don't send any objects in the "(unused)" range, we can't copy the delta'd object directly, since its delta offset includes a range of the pack that we didn't copy, so we have to account for that difference when patching and reassembling the delta. In order to compute this value correctly, we need to know not only where we are in the packfile we're assembling (with `hashfile_total(f)`) but also the position of the first byte of the packfile that we are currently reusing. Currently, this works just fine, since when reusing only a single pack those two values are always identical (because verbatim reuse is the first thing pack-objects does when enabled after writing the pack header). But when reusing multiple packs which have one or more gaps, we'll need to account for these two values diverging. Together, these two allow us to compute the reused chunk's offset difference relative to the start of the reused pack, as desired. Helped-by: Jeff King <[email protected]> Signed-off-by: Taylor Blau <[email protected]> Signed-off-by: Junio C Hamano <[email protected]>
1 parent 5e29c3f commit d1d701e

File tree

1 file changed

+8
-3
lines changed

1 file changed

+8
-3
lines changed

builtin/pack-objects.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,6 +1015,7 @@ static off_t find_reused_offset(off_t where)
10151015

10161016
static void write_reused_pack_one(struct packed_git *reuse_packfile,
10171017
size_t pos, struct hashfile *out,
1018+
off_t pack_start,
10181019
struct pack_window **w_curs)
10191020
{
10201021
off_t offset, next, cur;
@@ -1024,7 +1025,8 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile,
10241025
offset = pack_pos_to_offset(reuse_packfile, pos);
10251026
next = pack_pos_to_offset(reuse_packfile, pos + 1);
10261027

1027-
record_reused_object(offset, offset - hashfile_total(out));
1028+
record_reused_object(offset,
1029+
offset - (hashfile_total(out) - pack_start));
10281030

10291031
cur = offset;
10301032
type = unpack_object_header(reuse_packfile, w_curs, &cur, &size);
@@ -1094,6 +1096,7 @@ static void write_reused_pack_one(struct packed_git *reuse_packfile,
10941096

10951097
static size_t write_reused_pack_verbatim(struct packed_git *reuse_packfile,
10961098
struct hashfile *out,
1099+
off_t pack_start UNUSED,
10971100
struct pack_window **w_curs)
10981101
{
10991102
size_t pos = 0;
@@ -1125,10 +1128,12 @@ static void write_reused_pack(struct packed_git *reuse_packfile,
11251128
{
11261129
size_t i = 0;
11271130
uint32_t offset;
1131+
off_t pack_start = hashfile_total(f) - sizeof(struct pack_header);
11281132
struct pack_window *w_curs = NULL;
11291133

11301134
if (allow_ofs_delta)
1131-
i = write_reused_pack_verbatim(reuse_packfile, f, &w_curs);
1135+
i = write_reused_pack_verbatim(reuse_packfile, f, pack_start,
1136+
&w_curs);
11321137

11331138
for (; i < reuse_packfile_bitmap->word_alloc; ++i) {
11341139
eword_t word = reuse_packfile_bitmap->words[i];
@@ -1145,7 +1150,7 @@ static void write_reused_pack(struct packed_git *reuse_packfile,
11451150
* for why.
11461151
*/
11471152
write_reused_pack_one(reuse_packfile, pos + offset, f,
1148-
&w_curs);
1153+
pack_start, &w_curs);
11491154
display_progress(progress_state, ++written);
11501155
}
11511156
}

0 commit comments

Comments
 (0)