╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────────────╮ │src/ui/Repo/Files.zig│ ╰─────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │184 // their first window (for the in-page detail when selected). │ │185 const is_selected = if (selected_file) |sf| std.mem.eql(u8, sf, name) else false; │ │186 const window_start = if (is_selected) after else 0; │ │168 - const content = readFileContent(state, io, gpa, aa, file_path, tree_entry, window_start) catch │ │187 + const content = readFileContent(repo_opts, state, io, gpa, aa, file_path, tree_entry, window_start) catch│ │188 FileContent{ .lines = &.{} }; │ │189 entry.lines = content.lines; │ │190 entry.is_binary = content.is_binary; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────╮ │219 // line iterator flags binary files (its source becomes `.binary`), in which case│ │220 // we report no lines and let the view show a placeholder. │ │221 fn readFileContent( │ │203 - state: rp.Repo(.xit, .{}).State(.read_only), │ │222 + comptime repo_opts: rp.RepoOpts(.xit), │ │223 + state: rp.Repo(.xit, repo_opts).State(.read_only), │ │224 io: std.Io, │ │225 gpa: std.mem.Allocator, │ │226 arena: std.mem.Allocator, │ ╰──────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │227 path: []const u8, │ │208 - tree_entry: tr.TreeEntry((rp.RepoOpts(.xit){}).hash), │ │228 + tree_entry: tr.TreeEntry(repo_opts.hash), │ │229 start: usize, │ │230 ) !FileContent { │ │211 - var line_iter = try df.LineIterator(.xit, .{}).initFromTree(state, io, gpa, path, tree_entry); │ │231 + var line_iter = try df.LineIterator(.xit, repo_opts).initFromTree(state, io, gpa, path, tree_entry);│ │232 defer line_iter.deinit(); │ │233 if (line_iter.source == .binary) return .{ .lines = &.{}, .is_binary = true }; │ │234 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │251 } │ │252 │ │253 // an empty listing pinned to a ref, for the wasm / no-repo / unresolved paths. │ │234 -fn emptyResult(aa: std.mem.Allocator, identity: []const u8, ref_or_oid: RefOrOid, ref_or_oid_value: []const u8, dir: []const u8) !Self { │ │254 +fn emptyResult(aa: std.mem.Allocator, identity: []const u8, ref_or_oid: ui.RoutablePage.RefOrOid, ref_or_oid_value: []const u8, dir: []const u8) !Self {│ │255 return .{ │ │256 .identity = try aa.dupe(u8, identity), │ │257 .ref_or_oid = ref_or_oid, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────╮ │src/ui/Repo/Refs.zig│ ╰────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │71 // open with the arena's backing allocator (transient; the ref names are │ │72 // duped into the page arena so they outlive the repo handle). │ │73 const gpa = arena.child_allocator; │ │74 - var repo = rp.Repo(.xit, .{}).open(io, gpa, .{ .path = repo_path }) catch return empty; │ │75 - defer repo.deinit(io, gpa); │ │74 + var any_repo = rp.AnyRepo(.xit, .{}).open(io, gpa, .{ .path = repo_path }) catch return empty; │ │75 + defer any_repo.deinit(io, gpa); │ │76 │ │77 - var branch_iter = repo.listBranches(io, gpa, .{ .index = branches_after }) catch return empty; │ │78 - defer branch_iter.deinit(io); │ │79 - const branches = try collectWindow(io, aa, &branch_iter, branches_after); │ │77 + const branches, const tags = switch (any_repo) { │ │78 + inline else => |*repo| blk: { │ │79 + var branch_iter = repo.listBranches(io, gpa, .{ .index = branches_after }) catch return empty;│ │80 + defer branch_iter.deinit(io); │ │81 + const b = try collectWindow(io, aa, &branch_iter, branches_after); │ │82 │ │81 - var tag_iter = repo.listTags(io, gpa, .{ .index = tags_after }) catch return empty; │ │82 - defer tag_iter.deinit(io); │ │83 - const tags = try collectWindow(io, aa, &tag_iter, tags_after); │ │83 + var tag_iter = repo.listTags(io, gpa, .{ .index = tags_after }) catch return empty; │ │84 + defer tag_iter.deinit(io); │ │85 + const t = try collectWindow(io, aa, &tag_iter, tags_after); │ │86 + break :blk .{ b, t }; │ │87 + }, │ │88 + }; │ │89 │ │90 return .{ │ │91 .identity = empty.identity, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │379 .branch => .branch, │ │380 .tag => .tag, │ │381 }; │ │377 - const value = try ui.ResolvedRefOrOid.urlEncode(aa, name); │ │382 + const value = try ui.urlEncodeRef(aa, name); │ │383 const route = ui.RoutablePage.repoFilesRoute(identity, ref_or_oid, value, "", 0) orelse return error.RouteTooLong;│ │384 const url = try route.urlAlloc(page_arena); │ │385 return std.fmt.allocPrint(aa, "a:{s}", .{url}); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯