diff --git a/git.zig b/git.zig index a307093565929bd0d27eb31adde7e5951753c2b2..b9dba78efff677a7c90a0dfd7590ecb7e2dbb624 100644 --- a/git.zig +++ b/git.zig @@ -1098,143 +1098,14 @@ pub const Repository = struct { const base_pack_offset = pack_offset - offset; const base_obj = try r.getPackedObject(arena, null, pack_index, base_pack_offset); // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len }); - - const compressed_content = packedobj_fbs.rest()[0..size]; - var bufr = nio.FixedBufferStream([]const u8).init(compressed_content); - - var list: std.ArrayListUnmanaged(u8) = .empty; - defer list.deinit(r.gpa); - try list.ensureUnusedCapacity(r.gpa, size); - try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa)); - // std.log.debug("transformation data={d}", .{list.items}); - - var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items); - - var list2: std.ArrayListUnmanaged(u8) = .empty; - errdefer list2.deinit(r.gpa); - - var base_size: usize = 0; - while (true) { - const c2: usize = unpackedobj_fbs.takeByte(); - base_size = (base_size << 7) | (c2 & 0x7f); - if (c2 & 0x80 == 0) break; - base_size += 1; - } - // std.log.debug("base_size={d}", .{base_size}); - - var obj_size: usize = 0; - while (true) { - const c2: usize = unpackedobj_fbs.takeByte(); - obj_size = (obj_size << 7) | (c2 & 0x7f); - if (c2 & 0x80 == 0) break; - obj_size += 1; - } - // std.log.debug("obj_size={d}", .{obj_size}); - - while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) { - const c2 = unpackedobj_fbs.takeByte(); - if (c2 & 0x80 > 0) { - // copy range from base - var b: extras.RingBuffer(u8, 7) = .{}; - for (0..7) |i| { - const mask = @as(u8, 1) << @intCast(i); - b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0); - } - const start: u32 = @bitCast(b.items[0..4].*); - const nbytes: u24 = @bitCast(b.items[4..7].*); - // std.log.debug("- copy from base: start={d} nbytes={d}", .{ start, nbytes }); - const bytes = base_obj.content[start..][0..nbytes]; - // std.log.debug("{s}\n", .{bytes}); - try list2.appendSlice(r.gpa, bytes); - } else { - // append new data - const nbytes = c2 & 0x7f; - // std.log.debug("- append new bytes={d}", .{nbytes}); - if (nbytes == 0) continue; - const bytes = unpackedobj_fbs.takeSlice(nbytes); - // std.log.debug("{s}\n", .{bytes}); - try list2.appendSlice(r.gpa, bytes); - } - } - - // std.log.debug("- done", .{}); - // std.log.debug("{s}\n", .{list2.items}); - const _type = base_obj.type; - const content = try list2.toOwnedSlice(r.gpa); - const obj: GitObject = .{ .type = _type, .content = content }; - if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); - return obj; + return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj); }, .ref_delta => { // std.log.debug("type={s} size={d}", .{ @tagName(ty), size }); const base_oid = extras.to_hex(packedobj_fbs.takeSlice(20)[0..20].*); const base_obj = (try r.getObject(arena, &base_oid)).?; - - const compressed_content = packedobj_fbs.rest()[0..size]; - var bufr = nio.FixedBufferStream([]const u8).init(compressed_content); - - var list: std.ArrayListUnmanaged(u8) = .empty; - defer list.deinit(r.gpa); - try list.ensureUnusedCapacity(r.gpa, size); - try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa)); - // std.log.debug("transformation data={d}", .{list.items}); - - var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items); - - var list2: std.ArrayListUnmanaged(u8) = .empty; - errdefer list2.deinit(r.gpa); - - var base_size: usize = 0; - while (true) { - const c2: usize = unpackedobj_fbs.takeByte(); - base_size = (base_size << 7) | (c2 & 0x7f); - if (c2 & 0x80 == 0) break; - base_size += 1; - } - // std.log.debug("base_size={d}", .{base_size}); - - var obj_size: usize = 0; - while (true) { - const c2: usize = unpackedobj_fbs.takeByte(); - obj_size = (obj_size << 7) | (c2 & 0x7f); - if (c2 & 0x80 == 0) break; - obj_size += 1; - } - // std.log.debug("obj_size={d}", .{obj_size}); - - while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) { - const c2 = unpackedobj_fbs.takeByte(); - if (c2 & 0x80 > 0) { - // copy range from base - var b: extras.RingBuffer(u8, 7) = .{}; - for (0..7) |i| { - const mask = @as(u8, 1) << @intCast(i); - b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0); - } - const start: u32 = @bitCast(b.items[0..4].*); - const nbytes: u24 = @bitCast(b.items[4..7].*); - // std.log.debug("- copy from base: start={d} nbytes={d}", .{ start, nbytes }); - const bytes = base_obj.content[start..][0..nbytes]; - // std.log.debug("{s}\n", .{bytes}); - try list2.appendSlice(r.gpa, bytes); - } else { - // append new data - const nbytes = c2 & 0x7f; - // std.log.debug("- append new bytes={d}", .{nbytes}); - if (nbytes == 0) continue; - const bytes = unpackedobj_fbs.takeSlice(nbytes); - // std.log.debug("{s}\n", .{bytes}); - try list2.appendSlice(r.gpa, bytes); - } - } - - // std.log.debug("- done", .{}); - // std.log.debug("{s}\n", .{list2.items}); - const _type = base_obj.type; - const content = try list2.toOwnedSlice(r.gpa); - const obj: GitObject = .{ .type = _type, .content = content }; - if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); - return obj; + // std.log.debug("base: type={s} content=[{d}]", .{ @tagName(base_obj.type), base_obj.content.len }); + return r.getDeltadObject(maybe_oid, &packedobj_fbs, size, base_obj); }, } comptime unreachable; @@ -1246,6 +1117,74 @@ pub const Repository = struct { } } + fn getDeltadObject(r: *Repository, maybe_oid: ?Id, packedobj_fbs: *nio.FixedBufferStream([]const u8), size: usize, base_obj: GitObject) !GitObject { + const compressed_content = packedobj_fbs.rest()[0..size]; + var bufr = nio.FixedBufferStream([]const u8).init(compressed_content); + + var list: std.ArrayListUnmanaged(u8) = .empty; + defer list.deinit(r.gpa); + try list.ensureUnusedCapacity(r.gpa, size); + try std.compress.flate.inflate.decompress(.zlib, bufr.anyReadable(), list.writer(r.gpa)); + // std.log.debug("transformation data={d}", .{list.items}); + + var unpackedobj_fbs = nio.FixedBufferStream([]const u8).init(list.items); + + var list2: std.ArrayListUnmanaged(u8) = .empty; + errdefer list2.deinit(r.gpa); + + var base_size: usize = 0; + while (true) { + const c2: usize = unpackedobj_fbs.takeByte(); + base_size = (base_size << 7) | (c2 & 0x7f); + if (c2 & 0x80 == 0) break; + base_size += 1; + } + // std.log.debug("base_size={d}", .{base_size}); + + var obj_size: usize = 0; + while (true) { + const c2: usize = unpackedobj_fbs.takeByte(); + obj_size = (obj_size << 7) | (c2 & 0x7f); + if (c2 & 0x80 == 0) break; + obj_size += 1; + } + // std.log.debug("obj_size={d}", .{obj_size}); + + while (unpackedobj_fbs.pos < unpackedobj_fbs.buffer.len) { + const c2 = unpackedobj_fbs.takeByte(); + if (c2 & 0x80 > 0) { + // copy range from base + var b: extras.RingBuffer(u8, 7) = .{}; + for (0..7) |i| { + const mask = @as(u8, 1) << @intCast(i); + b.append(if (c2 & mask > 0) unpackedobj_fbs.takeByte() else 0); + } + const start: u32 = @bitCast(b.items[0..4].*); + const nbytes: u24 = @bitCast(b.items[4..7].*); + // std.log.debug("- copy from base: start={d} nbytes={d}", .{ start, nbytes }); + const bytes = base_obj.content[start..][0..nbytes]; + // std.log.debug("{s}\n", .{bytes}); + try list2.appendSlice(r.gpa, bytes); + } else { + // append new data + const nbytes = c2 & 0x7f; + // std.log.debug("- append new bytes={d}", .{nbytes}); + if (nbytes == 0) continue; + const bytes = unpackedobj_fbs.takeSlice(nbytes); + // std.log.debug("{s}\n", .{bytes}); + try list2.appendSlice(r.gpa, bytes); + } + } + + // std.log.debug("- done", .{}); + // std.log.debug("{s}\n", .{list2.items}); + const _type = base_obj.type; + const content = try list2.toOwnedSlice(r.gpa); + const obj: GitObject = .{ .type = _type, .content = content }; + if (maybe_oid) |oid| try r.unpacked_objects.put(r.gpa, oid, obj); + return obj; + } + const GitObject = struct { type: RefType, content: []const u8,