╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭────────────────────────────────────────────────────────╮ │57 pub fn init( │ │58 arena: *std.heap.ArenaAllocator, │ │59 session: *ui.Session, │ │60 - event_id: *const [evt.event_id_size]u8, │ │60 + source_maybe: ?ui.RepoSource, │ │61 identity: []const u8, │ │62 requested_ref_or_oid: ?ui.RoutablePage.RefOrOid,│ │63 requested_value: []const u8, │ ╰────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────╮ │66 after: usize, │ │67 ) !Self { │ │68 const aa = arena.allocator(); │ │69 - const hex = std.fmt.bytesToHex(event_id.*, .lower); │ │69 │ │70 // no filesystem (wasm) or nowhere to look: empty listing. the wasm path│ │71 // never calls init anyway — it rebuilds from the serialized snapshot. │ ╰────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │72 const io = session.io orelse return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value); │ │74 - const repos_dir = session.repos_dir orelse return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value);│ │75 - │ │76 - const repo_path = try std.fs.path.join(aa, &.{ repos_dir, &hex }); │ │73 + const source = source_maybe orelse return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value); │ │74 │ │75 // walk the log with the arena's backing allocator (transient; the commits │ │76 // we keep are duped into the page arena so they outlive it). AnyRepo opens │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 77 // both sha1 and sha256 repos. │ │ 78 const gpa = arena.child_allocator; │ │ 82 - var any_repo = rp.AnyRepo(.xit, .{}).open(io, gpa, .{ .path = repo_path }) catch return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value); │ │ 83 - defer any_repo.deinit(io, gpa); │ │ 79 + switch (source.repo_kind) { │ │ 80 + inline else => |repo_kind| { │ │ 81 + var any_repo = rp.AnyRepo(repo_kind, .{}).open(io, gpa, .{ .path = source.path }) catch return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value);│ │ 82 + defer any_repo.deinit(io, gpa); │ │ 83 │ │ 85 - return switch (any_repo) { │ │ 86 - inline else => |*repo| collect(repo.self_repo_opts, arena, repo, io, gpa, identity, requested_ref_or_oid, requested_value, after), │ │ 87 - }; │ │ 84 + return switch (any_repo) { │ │ 85 + inline else => |*repo| collect(repo_kind, repo.self_repo_opts, arena, repo, io, gpa, identity, requested_ref_or_oid, requested_value, after), │ │ 86 + }; │ │ 87 + }, │ │ 88 + } │ │ 89 } │ │ 90 │ │ 90 -// walk the log for an opened repo. generic over the repo's hash kind so the │ │ 91 -// oid buffers and diff types it threads through match the repo's opts. │ │ 91 +// walk the log for an opened repo. generic over the repo's backend and hash │ │ 92 +// kind so the oid buffers and diff types it threads through match the repo's │ │ 93 +// opts. │ │ 94 fn collect( │ │ 93 - comptime repo_opts: rp.RepoOpts(.xit), │ │ 95 + comptime repo_kind: rp.RepoKind, │ │ 96 + comptime repo_opts: rp.RepoOpts(repo_kind), │ │ 97 arena: *std.heap.ArenaAllocator, │ │ 95 - repo: *rp.Repo(.xit, repo_opts), │ │ 98 + repo: *rp.Repo(repo_kind, repo_opts), │ │ 99 io: std.Io, │ │100 gpa: std.mem.Allocator, │ │101 identity: []const u8, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │104 after: usize, │ │105 ) !Self { │ │106 const aa = arena.allocator(); │ │104 - const hex_len = ui.ResolvedRefOrOid(repo_opts).hex_len; │ │107 + const hex_len = ui.ResolvedRefOrOid(repo_kind, repo_opts).hex_len; │ │108 │ │109 // resolve the requested ref (or the default branch) to the commit oid to│ │110 // walk from. an explicitly named ref that doesn't resolve is a bad url │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │111 // (NotFound -> 404); the default-branch path falls through to empty. │ │109 - const resolved = (try ui.ResolvedRefOrOid(repo_opts).init(repo, io, aa, requested_ref_or_oid, requested_value)) orelse { │ │112 + const resolved = (try ui.ResolvedRefOrOid(repo_kind, repo_opts).init(repo, io, aa, requested_ref_or_oid, requested_value)) orelse {│ │113 if (requested_ref_or_oid != null) return error.NotFound; │ │114 return emptyResult(aa, identity, .branch, requested_value); │ │115 }; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │155 // the selected commit (the first, == start_oid) shows the window the │ │156 // url asks for; the rest show their first window. │ │157 const start = if (i == 0) after else 0; │ │155 - const rendered = renderCommitDiff(repo_opts, io, gpa, aa, repo, oid, start, diff_page) catch │ │158 + const rendered = renderCommitDiff(repo_kind, repo_opts, io, gpa, aa, repo, oid, start, diff_page) catch│ │159 RenderedDiff{ .hunks = &.{}, .has_prev = false, .has_more = false }; │ │160 commit.hunks = rendered.hunks; │ │161 commit.window_start = start; │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────╮ │195 // render the window [start, start+len) of a commit's diff against its first│ │196 // parent into `arena`-owned hunks. has_prev/has_more flag adjacent windows.│ │197 fn renderCommitDiff( │ │195 - comptime repo_opts: rp.RepoOpts(.xit), │ │198 + comptime repo_kind: rp.RepoKind, │ │199 + comptime repo_opts: rp.RepoOpts(repo_kind), │ │200 io: std.Io, │ │201 gpa: std.mem.Allocator, │ │202 arena: std.mem.Allocator, │ ╰─────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────╮ │199 - repo: *rp.Repo(.xit, repo_opts), │ │203 + repo: *rp.Repo(repo_kind, repo_opts), │ │204 oid: [xit.hash.hexLen(repo_opts.hash)]u8,│ │205 start: usize, │ │206 len: usize, │ ╰──────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │229 var pair = pair_val; │ │230 defer pair.deinit(); │ │231 │ │228 - var hunk_iter = df.HunkIterator(.xit, repo_opts).init(gpa, &pair.a, &pair.b) catch continue; │ │232 + var hunk_iter = df.HunkIterator(repo_kind, repo_opts).init(gpa, &pair.a, &pair.b) catch continue;│ │233 defer hunk_iter.deinit(gpa); │ │234 │ │235 // the path label rides on the first of this file's hunks we actually show. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯