╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────────────────────────────────────╮ │1 const std = @import("std"); │ │2 -const builtin = @import("builtin"); │ │2 const evt = @import("../../event.zig");│ │3 const ui = @import("../../ui.zig"); │ │4 const xit = @import("xit"); │ ╰──────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │23 // limit. │ │24 const max_message_size = 100 * 1024; │ │25 │ │27 -// one commit on the current page, with its diff against its first parent │ │28 -// pre-rendered up to the budget so the web client can show it without a repo.│ │26 +// one commit on the current page. │ │27 pub const Commit = struct { │ │28 oid: []const u8, │ │29 + // what its diff is against: the first parent, all zeros for a root commit│ │30 + parent_oid: []const u8, │ │31 date: []const u8, // "YYYY-MM-DD" │ │32 message: []const u8, // trimmed, may be multi-line │ │33 // whether `message` is a shortened preview. │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │40 // whether it has a second parent. │ │41 merge: bool = false, │ │42 stats: ?xit.patch.CommitStats = null, │ │43 - window: Diff.Window = .{}, │ │43 }; │ │44 │ │45 // where links and clone commands for this repository are rooted, and who views it.│ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │53 commits: []const Commit, │ │54 // the first oid of the next page, or null when this is the last page. │ │55 next_start: ?[]const u8, │ │57 -// what the pane shows for the commit the log walks from. │ │58 -content: Content = .{ .diff = .{} }, │ │56 +// the pane shows the whole message of the commit the log walks from. │ │57 +message: bool = false, │ │58 // the decoded query this list holds the results of, or null for a plain log.│ │59 search: ?[]const u8 = null, │ │60 // whether the viewed ref has a commit index, so the search box shows and a │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │67 no_commits: bool = false, │ │68 │ │69 const Self = @This(); │ │71 - │ │72 -// the diff and the message are alternatives, so a filtered diff can't also be│ │73 -// a message. the message page reads up to the safety limit above. │ │74 -pub const Content = union(enum) { │ │75 - diff: struct { │ │76 - // the file the top commit's diff is filtered to ("" = every file). │ │77 - path: []const u8 = "", │ │78 - }, │ │79 - message, │ │80 -}; │ │70 │ │71 // walk the log for an opened repo. generic over the repo's backend and hash │ │83 -// kind so the oid buffers and diff types it threads through match the repo's │ │84 -// opts. `content` is what the walk root's pane shows, the only commit any of │ │85 -// it applies to. walks with the arena's backing allocator (transient; the │ │86 -// commits we keep are duped into the page arena so they outlive it). │ │72 +// kind so the oid buffers it threads through match the repo's opts. `message`│ │73 +// reads the walk root's message whole, up to the safety limit above. walks │ │74 +// with the arena's backing allocator (transient; the commits we keep are │ │75 +// duped into the page arena so they outlive it). │ │76 pub fn init( │ │77 comptime repo_kind: rp.RepoKind, │ │78 comptime repo_opts: rp.RepoOpts(repo_kind), │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────╮ │ 86 handle: ui.RepoHandle, │ │ 87 requested_ref_or_oid: ?ui.RoutablePage.RefOrOid, │ │ 88 requested_value: []const u8, │ │100 - content: ui.RoutablePage.RepoCommitsRoute.Content,│ │ 89 + message: bool, │ │ 90 base_oid: []const u8, │ │ 91 search: []const u8, │ │ 92 from: []const u8, │ ╰───────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │101 } │ │102 const query: ?[]const u8 = if (search.len == 0) null else std.Uri.percentDecodeInPlace(try aa.dupe(u8, search));│ │103 │ │115 - // the walk root's message replaces its diff, so it's read whole and its │ │116 - // hunks aren't rendered. the window and the filter are its diff's. │ │117 - const root_message = std.meta.activeTag(content) == .message; │ │118 - const root_start: usize = switch (content) { │ │119 - .diff => |d| d.start, │ │120 - .message => 0, │ │121 - }; │ │122 - const root_path: []const u8 = switch (content) { │ │123 - .diff => |*d| d.path.slice(), │ │124 - .message => "", │ │125 - }; │ │126 - │ │104 // resolve the requested ref (or the default branch) to the commit oid to │ │105 // walk from. an explicitly named ref that doesn't resolve is a bad url │ │106 // (NotFound -> 404); the default-branch path falls through to empty. │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │107 var resolved = (try ui.ResolvedRefOrOid(repo_kind, repo_opts).init(repo, io, aa, requested_ref_or_oid, requested_value)) orelse {│ │108 if (requested_ref_or_oid != null) return error.NotFound; │ │132 - var data = try emptyResult(aa, handle, .branch, requested_value, content, base_oid); │ │109 + var data = try emptyResult(aa, handle, .branch, requested_value, base_oid); │ │110 data.no_commits = true; │ │111 return data; │ │112 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │113 │ │137 - var moment = repo.core.latestMoment() catch return emptyResult(aa, handle, resolved.ref_or_oid, resolved.value, content, base_oid);│ │114 + var moment = repo.core.latestMoment() catch return emptyResult(aa, handle, resolved.ref_or_oid, resolved.value, base_oid); │ │115 const state = rp.Repo(repo_kind, repo_opts).State(.read_only){ .core = &repo.core, .extra = .{ .moment = &moment } }; │ │116 │ │117 // resolve annotated tags once, independently of the page's starting commit. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │118 { │ │119 var tip = obj.Object(repo_kind, repo_opts).initCommit(state, io, gpa, &resolved.oid) catch {│ │120 if (query != null) return error.NotFound; │ │144 - return emptyResult(aa, handle, resolved.ref_or_oid, resolved.value, content, base_oid); │ │121 + return emptyResult(aa, handle, resolved.ref_or_oid, resolved.value, base_oid); │ │122 }; │ │123 defer tip.deinit(); │ │124 resolved.oid = tip.oid; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯