╭ changed ───╮ │src/push.zig│ ╰────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────╮ │120 } │ │121 }; │ │122 │ │123 - try repo.core.db_file.lock(io, .exclusive); │ │124 - defer repo.core.db_file.unlock(io); │ │123 + const result = blk: { │ │124 + try repo.core.db_file.lock(io, .exclusive); │ │125 + defer repo.core.db_file.unlock(io); │ │126 │ │126 - const history = try DB.ArrayList(.read_write).init(repo.core.db.rootCursor()); │ │127 - history.appendContext( │ │128 - .{ .slot = try history.getSlot(-1) }, │ │129 - Ctx{ │ │130 - .core = &repo.core, │ │131 - .io = io, │ │132 - .allocator = allocator, │ │133 - .reader = reader, │ │134 - .writer = writer, │ │135 - .options = options, │ │136 - .response = &response, │ │137 - .repo_root_path = repo_root_path, │ │138 - .error_writer = error_writer, │ │139 - }, │ │140 - ) catch |err| { │ │127 + const history = try DB.ArrayList(.read_write).init(repo.core.db.rootCursor());│ │128 + break :blk history.appendContext( │ │129 + .{ .slot = try history.getSlot(-1) }, │ │130 + Ctx{ │ │131 + .core = &repo.core, │ │132 + .io = io, │ │133 + .allocator = allocator, │ │134 + .reader = reader, │ │135 + .writer = writer, │ │136 + .options = options, │ │137 + .response = &response, │ │138 + .repo_root_path = repo_root_path, │ │139 + .error_writer = error_writer, │ │140 + }, │ │141 + ); │ │142 + }; │ │143 + result catch |err| { │ │144 response.finish(writer, @errorName(err)) catch {}; │ │145 if (err == error.CancelTransaction) return; │ │146 return err; │ ╰───────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │191 const target_oid = (try target_repo.readRef(io, .{ .kind = .head, .name = target_branch })) orelse return error.TargetNotFound;│ │192 const newest = try evt.PatchRev.readNewest(evt.EventDB(repo_opts.hash), repo_opts.hash, fork_moment, &arena); │ │193 var revision_id_maybe: ?[evt.event_id_size]u8 = null; │ │194 + var response = xit.net_server_receive_pack.Response.init(allocator); │ │195 + defer response.deinit(); │ │196 │ │197 // execute a transaction that receives the push and materializes its revision │ │193 - { │ │194 - var response = xit.net_server_receive_pack.Response.init(allocator); │ │195 - defer response.deinit(); │ │198 + const result = blk: { │ │199 const DB = rp.Repo(.xit, repo_opts).DB; │ │200 const State = rp.Repo(.xit, repo_opts).State; │ │201 const Ctx = struct { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────╮ │332 defer fork_repo.core.db_file.unlock(io); │ │333 │ │334 const history = try DB.ArrayList(.read_write).init(fork_repo.core.db.rootCursor());│ │332 - history.appendContext(.{ .slot = try history.getSlot(-1) }, Ctx{ │ │335 + break :blk history.appendContext(.{ .slot = try history.getSlot(-1) }, Ctx{ │ │336 .core = &fork_repo.core, │ │337 .target_core = &target_repo.core, │ │338 .io = io, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │349 .timestamp = timestamp, │ │350 .newest = newest, │ │351 .revision_id_maybe = &revision_id_maybe, │ │349 - }) catch |err| { │ │350 - response.finish(writer, @errorName(err)) catch {}; │ │351 - if (err == error.CancelTransaction) return; │ │352 - return err; │ │353 - }; │ │354 - try response.finish(writer, null); │ │355 - } │ │352 + }); │ │353 + }; │ │354 + result catch |err| { │ │355 + response.finish(writer, @errorName(err)) catch {}; │ │356 + if (err == error.CancelTransaction) return; │ │357 + return err; │ │358 + }; │ │359 │ │360 // best-effort update the published patch so it has the new revision │ │358 - { │ │359 - const revision_id = revision_id_maybe orelse return; │ │360 - if (!published) return; │ │361 + update: { │ │362 + const revision_id = revision_id_maybe orelse break :update; │ │363 + if (!published) break :update; │ │364 var update_arena = std.heap.ArenaAllocator.init(allocator); │ │365 defer update_arena.deinit(); │ │363 - const target_update_moment = evt.currentMoment(repo_opts, target_repo) catch return; │ │364 - const published_patch = (evt.Patch.readById(evt.EventDB(repo_opts.hash), repo_opts.hash, target_update_moment, &update_arena, &patch_id) catch return) orelse return; │ │365 - if (published_patch.removed) return; │ │366 - const fork_update_moment = evt.currentMoment(repo_opts, fork_repo) catch return; │ │367 - const revision = (evt.PatchRev.readById(evt.EventDB(repo_opts.hash), repo_opts.hash, fork_update_moment, &update_arena, &revision_id) catch return) orelse return; │ │368 - if (revision.removed) return; │ │366 + const target_update_moment = evt.currentMoment(repo_opts, target_repo) catch break :update; │ │367 + const published_patch = (evt.Patch.readById(evt.EventDB(repo_opts.hash), repo_opts.hash, target_update_moment, &update_arena, &patch_id) catch break :update) orelse break :update;│ │368 + if (published_patch.removed) break :update; │ │369 + const fork_update_moment = evt.currentMoment(repo_opts, fork_repo) catch break :update; │ │370 + const revision = (evt.PatchRev.readById(evt.EventDB(repo_opts.hash), repo_opts.hash, fork_update_moment, &update_arena, &revision_id) catch break :update) orelse break :update; │ │371 + if (revision.removed) break :update; │ │372 const selected = evt.Patch.Revision.fromRecord(revision_id, revision); │ │373 if (published_patch.event.revision) |current| { │ │371 - if (evt.fieldEqual(evt.Patch.Revision, current, selected)) return; │ │374 + if (evt.fieldEqual(evt.Patch.Revision, current, selected)) break :update; │ │375 } │ │376 var patch = published_patch.event; │ │377 patch.revision = selected; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │384 serve_common.logError(io, error_writer, "failed to update published patch {s}: {s}\n", .{ id, @errorName(update_err) });│ │385 }; │ │386 } │ │387 + │ │388 + // the client may read either repo as soon as it gets the final response. │ │389 + try response.finish(writer, null); │ │390 } │ │391 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯