╭ changed ───╮ │src/find.zig│ ╰────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭──────────╮ │← previous│ ╰──────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │221 const branch_hash = hash.hashInt(repo_opts.hash, ref.name); │ │222 const own = if (existing.fetchSwapRemove(branch_hash)) |kv| kv.value else null; │ │223 const oid = (try rf.readRecur(.xit, repo_opts, read_state, io, .{ .ref = .{ .kind = .head, .name = ref.name } })) orelse continue;│ │225 - const tree = try rootTreeOid(repo_opts, read_state, io, allocator, &oid); │ │226 - if (own) |entry| if (std.mem.eql(u8, &entry.tree, &tree)) continue; │ │227 - try work.append(aa, .{ .branch_hash = branch_hash, .tree = tree, .own = own }); │ │224 + if (own) |entry| if (std.mem.eql(u8, &entry.oid, &oid)) continue; │ │225 + try work.append(aa, .{ .branch_hash = branch_hash, .oid = oid, .own = own }); │ │226 } │ │227 │ │228 // whatever is left belongs to a branch that no longer exists │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │231 - for (existing.keys()) |branch_hash| try work.append(aa, .{ .branch_hash = branch_hash, .tree = null, .own = null });│ │229 + for (existing.keys()) |branch_hash| try work.append(aa, .{ .branch_hash = branch_hash, .oid = null, .own = null }); │ │230 } │ │231 │ │232 if (work.items.len == 0) return false; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │242 for (work.items) |item| { │ │243 if (progress.cancelled(repo_opts, progress_ctx_maybe)) return error.ClientGone; │ │244 const index = try DB.HashMap(.read_write).init(try moment.putCursor(index_hash));│ │247 - const tree = item.tree orelse { │ │245 + const tip = item.oid orelse { │ │246 _ = try index.remove(item.branch_hash); │ │247 continue; │ │248 }; │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────╮ │249 // the entry this one starts from (null = index the whole tree) │ │250 const from = item.own orelse new_branch_base; │ │251 │ │254 - var tree_bytes: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │255 - _ = try std.fmt.hexToBytes(&tree_bytes, &tree); │ │252 + var tip_bytes: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │253 + _ = try std.fmt.hexToBytes(&tip_bytes, &tip); │ │254 // putKey only fills an empty key slot, and this one changes │ │255 // whenever the branch moves │ │258 - var tree_cursor = try index.putKeyCursor(item.branch_hash); │ │259 - try tree_cursor.write(.{ .bytes = &tree_bytes }); │ │256 + var tip_cursor = try index.putKeyCursor(item.branch_hash); │ │257 + try tip_cursor.write(.{ .bytes = &tip_bytes }); │ │258 var files_cursor = try index.putCursor(item.branch_hash); │ │259 if (from) |entry| try files_cursor.write(.{ .slot = entry.files });│ │260 const files = try DB.SortedMap(.read_write).init(files_cursor); │ ╰────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │261 │ │262 + const tree = try rootTreeOid(repo_opts, state.readOnly(), io, allocator, &tip); │ │263 if (from) |entry| { │ │264 + const from_tree = try rootTreeOid(repo_opts, state.readOnly(), io, allocator, &entry.oid); │ │265 var tree_diff = tr.TreeDiff(.xit, repo_opts).init(allocator); │ │266 defer tree_diff.deinit(); │ │267 - try tree_diff.compare(state.readOnly(), io, &entry.tree, &tree, null); │ │267 + try tree_diff.compare(state.readOnly(), io, &from_tree, &tree, null); │ │268 progress.report(repo_opts, io, progress_ctx_maybe, .{ .start = .{ .kind = .writing_patch, .estimated_total_items = tree_diff.changes.count() } });│ │269 for (tree_diff.changes.keys(), tree_diff.changes.values()) |path, change| { │ │270 defer progress.report(repo_opts, io, progress_ctx_maybe, .{ .complete_one = .writing_patch }); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │288 │ │289 // the first entry ever written becomes the base for the next │ │290 // new branch, so only one branch walks a whole tree. │ │291 - if (new_branch_base == null) new_branch_base = .{ .tree = tree, .files = (try index.getSlot(item.branch_hash)) orelse unreachable };│ │291 + if (new_branch_base == null) new_branch_base = .{ .oid = tip, .files = (try index.getSlot(item.branch_hash)) orelse unreachable }; │ │292 // a later entry copies an earlier one's slot, so everything │ │293 // written so far has to be shared rather than mutated │ │294 try state.core.db.freeze(); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────╮ │329 } │ │330 } │ │331 │ │332 -// the root tree an index entry covers, read from its key slot as hex.│ │333 -fn readTree( │ │332 +// the tip an index entry covers, read from its key slot as hex. │ │333 +fn readOid( │ │334 comptime repo_opts: rp.RepoOpts(.xit), │ │335 key_cursor: rp.Repo(.xit, repo_opts).DB.Cursor(.read_only), │ │336 ) ![hash.hexLen(repo_opts.hash)]u8 { │ ╰───────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────╮ │337 - var tree: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │338 - if ((try key_cursor.readBytes(&tree)).len != tree.len) return error.InvalidFileIndex;│ │339 - return std.fmt.bytesToHex(tree, .lower); │ │337 + var oid: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │338 + if ((try key_cursor.readBytes(&oid)).len != oid.len) return error.InvalidFileIndex; │ │339 + return std.fmt.bytesToHex(oid, .lower); │ │340 } │ │341 │ │342 // build a file's key: its lowercased basename, a separator, then its full path. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────╯