╭ changed ───╮ │src/push.zig│ ╰────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────────────────────────────────╮ │87 var response = xit.net_server_receive_pack.Response.init(allocator); │ │88 defer response.deinit(); │ │89 │ │90 + var updates = xit.net_server_receive_pack.AppliedRefUpdates.init(allocator);│ │91 + defer updates.deinit(); │ │92 const Ctx = struct { │ │93 + updates: *xit.net_server_receive_pack.AppliedRefUpdates, │ │94 core: *rp.Repo(.xit, repo_opts).Core, │ │95 io: std.Io, │ │96 allocator: std.mem.Allocator, │ ╰────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │104 pub fn run(ctx: @This(), cursor: *DB.Cursor(.read_write)) !void { │ │105 var moment = try DB.HashMap(.read_write).init(cursor.*); │ │106 const state = State(.read_write){ .core = ctx.core, .extra = .{ .moment = &moment } }; │ │104 - var updates = xit.net_server_receive_pack.AppliedRefUpdates.init(ctx.allocator); │ │105 - defer updates.deinit(); │ │107 + │ │108 var receive_options = ctx.options; │ │107 - receive_options.applied_ref_updates = &updates; │ │109 + receive_options.applied_ref_updates = ctx.updates; │ │110 receive_options.deferred_response = ctx.response; │ │111 try xit.net_server_receive_pack.run(.xit, repo_opts, state, ctx.io, ctx.allocator, ctx.reader, ctx.writer, receive_options);│ │112 try writeReceivedPatches(repo_opts, state, ctx.io, ctx.allocator, ctx.response, ctx.writer); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │116 // transaction and must commit regardless. │ │117 if (null != try rf.readRecur(.xit, repo_opts, state.readOnly(), ctx.io, .{ .ref = evt.events_ref })) { │ │118 _ = try evt.consumeInTransaction(.repo, .xit, repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, evt.events_ref); │ │117 - try pch.detectMerged(repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, ctx.repo_root_path, updates.items.items, ctx.error_writer); │ │119 + try pch.detectMerged(repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, ctx.repo_root_path, ctx.updates.items.items, ctx.error_writer);│ │120 } │ │121 try xit.undo.writeMessage(repo_opts, state, .push); │ │122 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────╮ │130 break :blk history.appendContext( │ │131 .{ .slot = try history.getSlot(-1) },│ │132 Ctx{ │ │133 + .updates = &updates, │ │134 .core = &repo.core, │ │135 .io = io, │ │136 .allocator = allocator, │ ╰──────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │149 return err; │ │150 }; │ │151 │ │152 + pch.refreshBranches(.server, .xit, repo_opts, io, allocator, repo, updates.items.items) catch |err| { │ │153 + serve_common.logError(io, error_writer, "failed to refresh branch patches: {s}\n", .{@errorName(err)});│ │154 + }; │ │155 response.progress(writer, "Checking merges...\n") catch {}; │ │156 pch.refreshMergeability(repo_opts, io, allocator, repo, null); │ │157 try response.finish(writer, null); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │248 null; │ │249 │ │250 // reuse an identical revision or record a new one │ │251 + var revision_arena = std.heap.ArenaAllocator.init(ctx.allocator);│ │252 + defer revision_arena.deinit(); │ │253 var events: [2]evt.EventWithId = undefined; │ │254 var event_count: usize = 0; │ │247 - var base_tree_oid: [hash.hexLen(repo_opts.hash)]u8 = undefined; │ │248 - var head_tree_oid: [hash.hexLen(repo_opts.hash)]u8 = undefined; │ │249 - var tree_entries: [2]evt.EventTreeEntry = undefined; │ │255 if (existing_revision) |latest| { │ │256 if (ctx.published) ctx.revision_id_maybe.* = latest.id; │ │257 } else { │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │253 - var base_object = try obj.Object(.xit, repo_opts).initCommit(state.readOnly(), ctx.io, ctx.allocator, &base_oid); │ │254 - defer base_object.deinit(); │ │255 - var source_object = try obj.Object(.xit, repo_opts).initCommit(state.readOnly(), ctx.io, ctx.allocator, &source_oid); │ │256 - defer source_object.deinit(); │ │257 - base_tree_oid = base_object.content.commit.tree; │ │258 - head_tree_oid = source_object.content.commit.tree; │ │259 - │ │260 - var revision_id: [evt.event_id_size]u8 = undefined; │ │261 - ctx.io.random(&revision_id); │ │262 - const revision_hex = std.fmt.bytesToHex(revision_id, .lower); │ │263 - const revision_event: evt.PatchRev = .{ │ │264 - .base_oid = &base_oid, │ │265 - .source_oid = &source_oid, │ │266 - .message = ctx.title, │ │267 - }; │ │268 - const identity = try std.fmt.allocPrint(ctx.allocator, "{s} <{s}>", .{ ctx.author.name, ctx.author.email }); │ │269 - defer ctx.allocator.free(identity); │ │270 - const patch_oid = try evt.PatchRev.writeSquashCommit( │ │271 - .xit, │ │272 - repo_opts, │ │273 - state, │ │274 - ctx.io, │ │275 - ctx.allocator, │ │276 - revision_event, │ │277 - &head_tree_oid, │ │278 - identity, │ │279 - identity, │ │280 - ctx.timestamp, │ │281 - ); │ │282 - tree_entries = .{ │ │283 - .{ .tree = .{ .name = "base", .oid = &base_tree_oid } }, │ │284 - .{ .tree = .{ .name = "head", .oid = &head_tree_oid } }, │ │285 - }; │ │286 - events[event_count] = .{ │ │287 - .id = revision_hex, │ │288 - .timestamp = ctx.timestamp, │ │289 - .author = ctx.author, │ │290 - .tree_entries = &tree_entries, │ │291 - .event = .{ .patchrev = revision_event }, │ │292 - }; │ │258 + const prepared = try evt.PatchRev.prepare(.xit, repo_opts, state, ctx.io, &revision_arena, &base_oid, &source_oid, ctx.title, ctx.author, ctx.timestamp);│ │259 + events[event_count] = prepared.event; │ │260 event_count += 1; │ │294 - ctx.revision_id_maybe.* = revision_id; │ │261 + ctx.revision_id_maybe.* = try evt.parseEventId(&prepared.event.id); │ │262 │ │263 if (!ctx.published) { │ │264 var patch = ctx.patch.event; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────╮ │298 - patch.revision = .{ │ │299 - .id = revision_hex, │ │300 - .squash_oid = &patch_oid, │ │301 - .source_oid = &source_oid, │ │302 - }; │ │265 + patch.revision = prepared.revision;│ │266 events[event_count] = .{ │ │267 .id = ctx.patch_id, │ │268 .timestamp = ctx.timestamp, │ ╰────────────────────────────────────────────────────────────────╯