╭ changed ───╮ │src/fork.zig│ ╰────────────╯ ╭─────────────────────────────────────────────────────────────╮ │10 │ │11 pub const ref = rf.Ref{ .kind = .head, .name = "patch" };│ │12 │ │13 +// the action creating a fork records │ │14 +pub const undo_action = "haxy/fork"; │ │15 + │ │16 pub const Route = struct { │ │17 identity: []const u8, │ │18 id: [evt.event_id_size * 2]u8, │ ╰─────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │152 try bch.add(.xit, repo_opts, state, ctx.io, .{ .name = ref.name, .target = .none }); │ │153 } │ │154 try rf.replaceHead(.xit, repo_opts, state, ctx.io, .{ .ref = ref }); │ │152 - try xit.undo.write(repo_opts, state, std.Io.Timestamp.now(ctx.io, .real).toSeconds(), .{ .custom = .{ .action = "create_fork" } });│ │155 + try xit.undo.write(repo_opts, state, std.Io.Timestamp.now(ctx.io, .real).toSeconds(), .{ .custom = .{ .action = undo_action } }); │ │156 } │ │157 }; │ │158 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────╮ │src/patch.zig│ ╰─────────────╯ ╭─────────────────────────────────────────────────────────╮ │11 const fork = @import("fork.zig"); │ │12 const serve_common = @import("serve_common.zig"); │ │13 │ │14 +// the action a patch merge records │ │15 +pub const merge_undo_action = "haxy/merge"; │ │16 + │ │17 // capture an existing branch without creating a fork│ │18 pub fn writeBranchPatch( │ │19 host_kind: evt.HostKind, │ ╰─────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │954 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;│ │955 │ │956 // record the merge as one undoable action. │ │954 - try xit.undo.write(repo_opts, state, std.Io.Timestamp.now(ctx.io, .real).toSeconds(), .{ .custom = .{ .action = "merge_patch" } }); │ │957 + try xit.undo.write(repo_opts, state, std.Io.Timestamp.now(ctx.io, .real).toSeconds(), .{ .custom = .{ .action = merge_undo_action } }); │ │958 } │ │959 }; │ │960 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/test/undo.zig│ ╰─────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │17 defer repo.deinit(io, allocator); │ │18 var arena = std.heap.ArenaAllocator.init(allocator); │ │19 defer arena.deinit(); │ │20 - const initial = try Undo.init(opts, &arena, &repo, "", null); │ │20 + const initial = try Undo.init(opts, &arena, &repo, null, "", null); │ │21 try std.testing.expectEqual(1, initial.count); │ │22 for (0..25) |index| { │ │23 const value = try std.fmt.allocPrint(arena.allocator(), "{d}", .{index});│ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │24 try repo.addConfig(io, allocator, .{ .name = "undo.value", .value = value });│ │25 } │ │26 - const first = try Undo.init(opts, &arena, &repo, "", null); │ │26 + const first = try Undo.init(opts, &arena, &repo, null, "", null); │ │27 try std.testing.expectEqual(20, first.items.len); │ │28 try std.testing.expectEqual(25, first.items[0].index); │ │29 - const second = try Undo.init(opts, &arena, &repo, "", first.next); │ │29 + const second = try Undo.init(opts, &arena, &repo, null, "", first.next); │ │30 try std.testing.expectEqual(6, second.items.len); │ │31 try std.testing.expectEqual(5, second.items[0].index); │ │32 try std.testing.expectEqual(0, second.items[5].index); │ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │33 try std.testing.expectEqual(null, second.next); │ │34 - try std.testing.expectError(error.NotFound, Undo.init(opts, &arena, &repo, "", 26)); │ │34 + try std.testing.expectError(error.NotFound, Undo.init(opts, &arena, &repo, null, "", 26));│ │35 try std.testing.expectError(error.InvalidHistoryIndex, repo.undo(io, 0)); │ │36 try std.testing.expectError(error.InvalidHistoryIndex, repo.undo(io, 26)); │ │37 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────╮ │40 try expectConfig(&repo, "23"); │ │41 try repo.undo(io, 10); │ │42 try expectConfig(&repo, "8"); │ │43 - const undone = try Undo.init(opts, &arena, &repo, "", null); │ │43 + const undone = try Undo.init(opts, &arena, &repo, null, "", null); │ │44 try std.testing.expectEqual(28, undone.count); │ │45 try std.testing.expectEqualStrings("undo", undone.items[0].action);│ │46 try repo.undo(io, undone.items[0].index); │ ╰───────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────╮ │121 var repo = try xit.repo.Repo(.xit, .{}).open(io, allocator, .{ .path = path });│ │122 defer repo.deinit(io, allocator); │ │123 try expectConfig(&repo, "first"); │ │124 - const data = try Undo.init(.{}, &arena, &repo, "alice/demo", null); │ │124 + const data = try Undo.init(.{}, &arena, &repo, null, "alice/demo", null); │ │125 try std.testing.expectEqualStrings("undo", data.items[0].action); │ │126 } │ │127 // keep the old session/page moment, but transfer ownership to the writer. │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │183 var repo = try xit.repo.Repo(.xit, opts).init(io, allocator, .{ .path = path }); │ │184 defer repo.deinit(io, allocator); │ │185 _ = try repo.commitAtRef(io, allocator, .{ .message = "example commit" }, null, .{ .kind = .head, .name = "master" });│ │186 - const data = try Undo.init(opts, &arena, &repo, "", null); │ │186 + const data = try Undo.init(opts, &arena, &repo, null, "", null); │ │187 try std.testing.expect(std.mem.startsWith(u8, data.items[0].description, "commit -m \"example commit\"")); │ │188 } │ │189 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯