Signed-off-by: Nguyễn Thái Ngọc Duy <[email protected]>
---
builtin/index-pack.c | 53 +++++++++++++++++++++++++++++++++++++---------------
1 file changed, 38 insertions(+), 15 deletions(-)
diff --git a/builtin/index-pack.c b/builtin/index-pack.c
index dc9961b..8a6e2a3 100644
--- a/builtin/index-pack.c
+++ b/builtin/index-pack.c
@@ -97,7 +97,7 @@ static unsigned char input_buffer[4096];
static unsigned int input_offset, input_len;
static off_t consumed_bytes;
static unsigned deepest_delta;
-static git_SHA_CTX input_ctx;
+static git_SHA_CTX input_ctx, output_ctx;
static uint32_t input_crc32;
static int input_fd, output_fd, pack_fd;
@@ -1511,6 +1511,7 @@ static void parse_pack_objects(unsigned char *sha1)
/* Got End-of-Pack signal? */
eop_byte = fill(1);
if (*eop_byte == 0) {
+ output_ctx = input_ctx;
git_SHA1_Update(&input_ctx, eop_byte, 1);
use(1);
/*
@@ -1540,7 +1541,8 @@ static void parse_pack_objects(unsigned char *sha1)
free(data);
display_progress(progress, i+1);
}
- objects[i].idx.offset = consumed_bytes;
+ nr_objects = i;
+ objects[nr_objects].idx.offset = consumed_bytes;
stop_progress(&progress);
if (!eop)
@@ -1634,7 +1636,7 @@ static void conclude_pack(int fix_thin_pack, const char
*curr_pack, unsigned cha
return;
}
- if (fix_thin_pack) {
+ if (fix_thin_pack && !packv4) {
struct sha1file *f;
unsigned char read_sha1[20], tail_sha1[20];
struct strbuf msg = STRBUF_INIT;
@@ -1661,6 +1663,26 @@ static void conclude_pack(int fix_thin_pack, const char
*curr_pack, unsigned cha
if (hashcmp(read_sha1, tail_sha1) != 0)
die(_("Unexpected tail checksum for %s "
"(disk corruption?)"), curr_pack);
+ } else if (fix_thin_pack && packv4) {
+ struct sha1file *f;
+ struct strbuf msg = STRBUF_INIT;
+ int nr_unresolved = nr_deltas - nr_resolved_deltas;
+ int nr_objects_initial = nr_objects;
+ if (nr_unresolved <= 0)
+ die(_("confusion beyond insanity"));
+ f = sha1fd(output_fd, curr_pack);
+ f->ctx = output_ctx; /* resume sha-1 from right before EOP */
+ fix_unresolved_deltas(f, nr_unresolved);
+ if (nr_objects != nr_objects_final)
+ die(_("pack number inconsistency, expected %u got %u"),
+ nr_objects, nr_objects_final);
+ strbuf_addf(&msg, _("completed with %d local objects"),
+ nr_objects_final - nr_objects_initial);
+ stop_progress_msg(&progress, msg.buf);
+ strbuf_release(&msg);
+ sha1close(f, pack_sha1, 0);
+ write_or_die(output_fd, pack_sha1, 20);
+ fsync_or_die(output_fd, f->name);
}
if (nr_deltas != nr_resolved_deltas)
die(Q_("pack has %d unresolved delta",
@@ -1700,16 +1722,15 @@ static struct object_entry *append_obj_to_pack(struct
sha1file *f,
{
struct object_entry *obj = &objects[nr_objects++];
unsigned char header[10];
- unsigned long s = size;
- int n = 0;
- unsigned char c = (type << 4) | (s & 15);
- s >>= 4;
- while (s) {
- header[n++] = c | 0x80;
- c = s & 0x7f;
- s >>= 7;
- }
- header[n++] = c;
+ int n;
+
+ if (packv4) {
+ if (nr_objects > nr_objects_final)
+ die(_("too many objects"));
+ /* TODO: convert OBJ_TREE to OBJ_PV4_TREE using pv4_encode_tree
*/
+ n = pv4_encode_object_header(type, size, header);
+ } else
+ n = encode_in_pack_object_header(type, size, header);
crc32_begin(f);
sha1write(f, header, n);
obj[0].size = size;
@@ -1748,7 +1769,8 @@ static void fix_unresolved_deltas(struct sha1file *f, int
nr_unresolved)
*/
sorted_by_pos = xmalloc(nr_unresolved * sizeof(*sorted_by_pos));
for (i = 0; i < nr_deltas; i++) {
- if (objects[deltas[i].obj_no].real_type != OBJ_REF_DELTA)
+ struct object_entry *obj = objects + deltas[i].obj_no;
+ if (obj->real_type != OBJ_REF_DELTA && !is_delta_tree(obj))
continue;
sorted_by_pos[n++] = &deltas[i];
}
@@ -1756,10 +1778,11 @@ static void fix_unresolved_deltas(struct sha1file *f,
int nr_unresolved)
for (i = 0; i < n; i++) {
struct delta_entry *d = sorted_by_pos[i];
+ struct object_entry *obj = objects + d->obj_no;
enum object_type type;
struct base_data *base_obj = alloc_base_data();
- if (objects[d->obj_no].real_type != OBJ_REF_DELTA)
+ if (obj->real_type != OBJ_REF_DELTA && !is_delta_tree(obj))
continue;
base_obj->data = read_sha1_file(d->base.sha1, &type,
&base_obj->size);
if (!base_obj->data)
--
1.8.2.83.gc99314b
--
To unsubscribe from this list: send the line "unsubscribe git" in
the body of a message to [email protected]
More majordomo info at http://vger.kernel.org/majordomo-info.html