╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────╮ │src/patch.zig│ ╰─────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │332 const DB = Repo.DB; │ │333 var arena = std.heap.ArenaAllocator.init(allocator); │ │334 defer arena.deinit(); │ │335 - const initial = try evt.Patch.readFromRepo(.xit, repo_opts, io, allocator, &arena, target_repo, id); │ │335 + const initial = try evt.readFromRepo(evt.Patch, .xit, repo_opts, io, allocator, &arena, target_repo, id);│ │336 if (initial) |record| if (record.removed or record.event.status.kind() != .open) return; │ │337 const repo_root_path = std.fs.path.dirname(target_repo.core.work_path) orelse "."; │ │338 const path = try fork.forkPath(arena.allocator(), repo_root_path, &std.fmt.bytesToHex(id.*, .lower)); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │714 } │ │715 const after_oid = (try rf.readRecur(.xit, repo_opts, state.readOnly(), ctx.io, .{ .ref = ctx.target_ref })) orelse return error.InvalidTargetBranch; │ │716 │ │717 - // import the revision and record the target's before/after range │ │717 + // retain the submitted revision and snapshot the merge result │ │718 if (!try importMergedRevision(repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, ctx.fork_repo, &ctx.patch_id, .{ .revision = ctx.revision, .before_oid = &before_oid, .after_oid = &after_oid }, ctx.expected_patch, ctx.author, ctx.timestamp)) return error.PatchOutOfDate;│ │719 │ │720 try xit.undo.writeMessage(repo_opts, state, .{ .custom = "merge patch" }); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │758 try merge(repo_opts, io, allocator, repo_root_path, target_repo, input); │ │759 var arena = std.heap.ArenaAllocator.init(allocator); │ │760 defer arena.deinit(); │ │761 - const record = (try evt.Patch.readFromRepo(.xit, repo_opts, io, allocator, &arena, target_repo, &try evt.parseEventId(&input.id))) orelse return error.InvalidPatch; │ │761 + const record = (try evt.readFromRepo(evt.Patch, .xit, repo_opts, io, allocator, &arena, target_repo, &try evt.parseEventId(&input.id))) orelse return error.InvalidPatch;│ │762 if (record.event.source_branch == null) try fork.remove(io, allocator, repo_root_path, admin_repo, &input.id, null, input.author); │ │763 } │ │764 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────╮ │809 allocator: std.mem.Allocator, │ │810 fork_repo: ?*rp.Repo(.xit, repo_opts), │ │811 patch_id: *const [evt.event_id_size]u8, │ │812 - merged: evt.Patch.Status.Merged, │ │812 + merged: struct { │ │813 + revision: evt.Patch.MergeRevision, │ │814 + before_oid: *const [hash.hexLen(repo_opts.hash)]u8,│ │815 + after_oid: *const [hash.hexLen(repo_opts.hash)]u8, │ │816 + }, │ │817 expected_patch: ?evt.Patch, │ │818 merged_author: ?evt.CommitAuthor, │ │819 merged_timestamp: u64, │ ╰────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │851 defer event_object.deinit(); │ │852 const original_author = try commitAuthor(event_object.content.commit.metadata.author orelse return false);│ │853 │ │850 - var events: [2]evt.EventWithId = undefined; │ │851 - var event_count: usize = 0; │ │854 + var events_buffer: [3]evt.EventWithId = undefined; │ │855 + var events: std.ArrayList(evt.EventWithId) = .initBuffer(&events_buffer); │ │856 var tree_entries: [2]evt.EventTreeEntry = undefined; │ │857 const needs_import = if (current_revision) |existing| existing.removed else true; │ │858 if (needs_import) { │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │860 .{ .tree = .{ .name = "base", .oid = revision.base_tree_oid } },│ │861 .{ .tree = .{ .name = "head", .oid = revision.head_tree_oid } },│ │862 }; │ │859 - events[event_count] = .{ │ │863 + events.appendAssumeCapacity(.{ │ │864 .id = selected.id, │ │865 .timestamp = event_object.content.commit.metadata.timestamp, │ │866 .author = original_author, │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │867 .tree_entries = &tree_entries, │ │868 .event = .{ .patchrev = revision.event }, │ │865 - }; │ │866 - event_count += 1; │ │869 + }); │ │870 } else { │ │871 const existing = current_revision orelse unreachable; │ │872 if (!selected.matches(existing)) return error.InvalidPatch;│ ╰────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │873 } │ │874 │ │875 + const author = merged_author orelse original_author; │ │876 + const timestamp = if (merged_author != null) merged_timestamp else @as(u64, @intCast(std.Io.Timestamp.now(io, .real).toSeconds())); │ │877 var patch = patch_record.event; │ │873 - patch.status = .{ .merged = merged }; │ │874 - events[event_count] = .{ │ │878 + const result = try evt.PatchRev.prepare(.xit, repo_opts, state, io, &arena, merged.before_oid, merged.after_oid, patch.title, author, timestamp);│ │879 + events.appendAssumeCapacity(result.event); │ │880 + patch.status = .{ .merged = .{ .revision = merged.revision, .patchrev_id = result.event.id } }; │ │881 + events.appendAssumeCapacity(.{ │ │882 .id = std.fmt.bytesToHex(patch_id.*, .lower), │ │876 - .timestamp = if (merged_author != null) merged_timestamp else @intCast(std.Io.Timestamp.now(io, .real).toSeconds()), │ │877 - .author = merged_author orelse original_author, │ │883 + .timestamp = timestamp, │ │884 + .author = author, │ │885 .event = .{ .patch = patch }, │ │879 - }; │ │880 - event_count += 1; │ │886 + }); │ │887 │ │882 - try evt.commitEvents(.xit, repo_opts, state, io, allocator, evt.events_ref, events[0..event_count], null); │ │888 + try evt.commitEvents(.xit, repo_opts, state, io, allocator, evt.events_ref, events.items, null); │ │889 if (!try evt.consumeInTransaction(.repo, .xit, repo_opts, state, db, moment, io, allocator, evt.events_ref)) return error.CancelTransaction; │ │890 return true; │ │891 } │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────────╮ │src/test/event/patch.zig│ ╰────────────────────────╯ ╭──────────────────────────────────────────────────────────────╮ │ 8 const fork = @import("../../fork.zig"); │ │ 9 const pch = @import("../../patch.zig"); │ │10 const push = @import("../../push.zig"); │ │11 +const ui = @import("../../ui.zig"); │ │12 │ │13 const repo_opts: rp.RepoOpts(.xit) = .{ .is_test = true };│ │14 const Repo = rp.Repo(.xit, repo_opts); │ ╰──────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │90 │ │91 // distinct branches at the same commit can still create a patch │ │92 try pch.writeBranchPatch(.local, kind, opts, io, allocator, &repo, std.fmt.bytesToHex(id, .lower), patch, null, author); │ │92 - const first = (try evt.Patch.readFromRepo(kind, opts, io, allocator, &arena, &repo, &id)) orelse return error.NotFound; │ │93 + const first = (try evt.readFromRepo(evt.Patch, kind, opts, io, allocator, &arena, &repo, &id)) orelse return error.NotFound;│ │94 const first_revision = first.event.revision orelse return error.NotFound; │ │95 try std.testing.expectEqualStrings(&base, first_revision.source_oid); │ │96 try std.testing.expectEqual(@as(?u64, if (kind == .xit) 0 else null), first_revision.commit_count); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯