╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────────────╮ │src/ui/Repo/Files.zig│ ╰─────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────╮ │27 identity: []const u8, │ │28 // the resolved ref this listing is read at (the default branch when the route│ │29 // didn't name one), so the view's directory links stay pinned to it. │ │30 -ref_kind: RefKindOrOid, │ │31 -ref_value: []const u8, │ │30 +ref_or_oid: RefOrOid, │ │31 +ref_or_oid_value: []const u8, │ │32 // the directory being viewed, relative to the repo root ("" at the root). │ │33 dir: []const u8, │ │34 entries: []const Entry, │ ╰──────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────╮ │40 session: *ui.Session, │ │41 event_id: *const [evt.event_id_size]u8,│ │42 identity: []const u8, │ │43 - req_kind: ?RefKindOrOid, │ │44 - req_value: []const u8, │ │43 + requested_ref_or_oid: ?RefOrOid, │ │44 + requested_value: []const u8, │ │45 dir: []const u8, │ │46 ) !Self { │ │47 const aa = arena.allocator(); │ ╰───────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │49 // no filesystem (wasm) or nowhere to look: empty listing pinned to whatever │ │50 // ref the route asked for. the wasm path never calls init anyway — it │ │51 // rebuilds from the serialized snapshot. │ │52 - const io = session.io orelse return emptyResult(aa, identity, req_kind orelse .branch, req_value, dir); │ │53 - const repos_dir = session.repos_dir orelse return emptyResult(aa, identity, req_kind orelse .branch, req_value, dir); │ │52 + const io = session.io orelse return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value, dir); │ │53 + const repos_dir = session.repos_dir orelse return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value, dir);│ │54 │ │55 // the repo's working copy lives at <repos_dir>/<hex event id>. │ │56 const hex = std.fmt.bytesToHex(event_id.*, .lower); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │60 // (transient; freed before init returns); the listing is built into the │ │61 // page arena so it outlives them. │ │62 const gpa = arena.child_allocator; │ │63 - var repo = rp.Repo(.xit, .{}).open(io, gpa, .{ .path = repo_path }) catch return emptyResult(aa, identity, req_kind orelse .branch, req_value, dir); │ │63 + var repo = rp.Repo(.xit, .{}).open(io, gpa, .{ .path = repo_path }) catch return emptyResult(aa, identity, requested_ref_or_oid orelse .branch, requested_value, dir);│ │64 defer repo.deinit(io, gpa); │ │65 │ │66 // resolve the effective ref: the one named in the route, else HEAD's branch. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │67 - // ref_value is duped immediately so it outlives the stack buffer head() fills.│ │68 - var eff_kind: RefKindOrOid = req_kind orelse .branch; │ │69 - var eff_value: []const u8 = req_value; │ │70 - if (req_kind == null) { │ │67 + // the value is duped immediately so it outlives the stack buffer head() fills.│ │68 + var resolved_ref_or_oid: RefOrOid = requested_ref_or_oid orelse .branch; │ │69 + var resolved_value: []const u8 = requested_value; │ │70 + if (requested_ref_or_oid == null) { │ │71 var head_buf: [rf.MAX_REF_CONTENT_SIZE]u8 = undefined; │ │72 if (repo.head(io, &head_buf)) |head| switch (head) { │ │73 .ref => |ref| { │ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────╮ │74 - eff_kind = .branch; │ │75 - eff_value = try aa.dupe(u8, ref.name); │ │74 + resolved_ref_or_oid = .branch; │ │75 + resolved_value = try aa.dupe(u8, ref.name);│ │76 }, │ │77 .oid => |oid| { │ │78 - eff_kind = .oid; │ │79 - eff_value = try aa.dupe(u8, oid); │ │78 + resolved_ref_or_oid = .object; │ │79 + resolved_value = try aa.dupe(u8, oid); │ │80 }, │ │81 } else |_| {} │ │82 } │ ╰───────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 84 // resolve the ref to the commit oid whose tree we list. a ref the route │ │ 85 // named explicitly that doesn't resolve is a bad url (NotFound -> 404); the │ │ 86 // default-branch path instead falls through to an empty listing below. │ │ 87 - const explicit = req_kind != null; │ │ 87 + const explicit = requested_ref_or_oid != null; │ │ 88 var oid: [hex_len]u8 = undefined; │ │ 89 - switch (eff_kind) { │ │ 90 - .oid => { │ │ 91 - if (eff_value.len != hex_len) return unresolved(aa, identity, explicit, eff_kind, eff_value, dir); │ │ 92 - @memcpy(&oid, eff_value); │ │ 89 + switch (resolved_ref_or_oid) { │ │ 90 + .object => { │ │ 91 + if (resolved_value.len != hex_len) return unresolved(aa, identity, explicit, resolved_ref_or_oid, resolved_value, dir);│ │ 92 + @memcpy(&oid, resolved_value); │ │ 93 }, │ │ 94 .branch, .tag => { │ │ 95 - const ref_kind: rf.RefKind = if (eff_kind == .branch) .head else .tag; │ │ 96 - oid = (repo.readRef(io, .{ .kind = ref_kind, .name = eff_value }) catch null) orelse │ │ 97 - return unresolved(aa, identity, explicit, eff_kind, eff_value, dir); │ │ 95 + const ref_kind: rf.RefKind = if (resolved_ref_or_oid == .branch) .head else .tag; │ │ 96 + oid = (repo.readRef(io, .{ .kind = ref_kind, .name = resolved_value }) catch null) orelse │ │ 97 + return unresolved(aa, identity, explicit, resolved_ref_or_oid, resolved_value, dir); │ │ 98 }, │ │ 99 } │ │100 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │101 // read the tree at that commit. building the read-only state mirrors what │ │102 // repo.status does internally, but for an arbitrary commit rather than HEAD. │ │103 - var moment = repo.core.latestMoment() catch return emptyResult(aa, identity, eff_kind, eff_value, dir); │ │103 + var moment = repo.core.latestMoment() catch return emptyResult(aa, identity, resolved_ref_or_oid, resolved_value, dir); │ │104 const state = rp.Repo(.xit, .{}).State(.read_only){ .core = &repo.core, .extra = .{ .moment = &moment } }; │ │105 - var tree = tr.Tree(.xit, .{}).init(state, io, gpa, &oid) catch return emptyResult(aa, identity, eff_kind, eff_value, dir); │ │105 + var tree = tr.Tree(.xit, .{}).init(state, io, gpa, &oid) catch return emptyResult(aa, identity, resolved_ref_or_oid, resolved_value, dir);│ │106 defer tree.deinit(); │ │107 │ │108 // collect the immediate children of `dir`. each committed path is a full │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────╮ │144 │ │145 return .{ │ │146 .identity = try aa.dupe(u8, identity), │ │147 - .ref_kind = eff_kind, │ │148 - .ref_value = try aa.dupe(u8, eff_value), │ │147 + .ref_or_oid = resolved_ref_or_oid, │ │148 + .ref_or_oid_value = try aa.dupe(u8, resolved_value),│ │149 .dir = try aa.dupe(u8, dir), │ │150 .entries = entries, │ │151 }; │ ╰─────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │153 │ │154 // a ref that didn't resolve: a 404 when the route named it explicitly, else an │ │155 // empty listing (e.g. resolving an empty repo's default branch). │ │156 -fn unresolved(aa: std.mem.Allocator, identity: []const u8, explicit: bool, ref_kind: RefKindOrOid, ref_value: []const u8, dir: []const u8) !Self { │ │156 +fn unresolved(aa: std.mem.Allocator, identity: []const u8, explicit: bool, ref_or_oid: RefOrOid, ref_or_oid_value: []const u8, dir: []const u8) !Self {│ │157 if (explicit) return error.NotFound; │ │158 - return emptyResult(aa, identity, ref_kind, ref_value, dir); │ │158 + return emptyResult(aa, identity, ref_or_oid, ref_or_oid_value, dir); │ │159 } │ │160 │ │161 // an empty listing pinned to a ref, for the wasm / no-repo / unresolved paths. │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯