╭ changed ──────╮ │src/test/ui.zig│ ╰───────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │165 const focus = view.getFocus(); │ │166 try view.build(allocator, .{ .min_size = .{ .width = null, .height = null }, .max_size = .{ .width = 100, .height = 30 } }, focus);│ │167 const box = &view.scroll.child.box; │ │168 - try std.testing.expectEqual(first.hunks.len * 2 + 1, box.children.count()); │ │168 + // the added files show only their paths, which link to their content │ │169 + try std.testing.expectEqual(first.hunks.len + 1, box.children.count()); │ │170 const file = ui.crossPageLink(focus, box.children.keys()[0], session.data) orelse return error.MissingFileLink; │ │171 const next = ui.crossPageLink(focus, box.children.keys()[box.children.count() - 1], session.data) orelse return error.MissingLink; │ │172 if (data.route == .repo) { │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │172 - try std.testing.expectEqualStrings("file-00.txt", file.repo_diff.path.slice()); │ │173 - try std.testing.expectEqualStrings(&base, file.repo_diff.base_oid.slice()); │ │173 + try std.testing.expectEqualStrings("file-00.txt", file.repo_files.path.slice());│ │174 + try std.testing.expectEqualStrings(&head, file.repo_files.ref_value.slice()); │ │175 try std.testing.expectEqualStrings(&base, next.repo_diff.base_oid.slice()); │ │176 try std.testing.expectEqualStrings(&head, next.repo_diff.value.slice()); │ │177 try std.testing.expectEqual(Diff.page_size, next.repo_diff.start); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │178 } else { │ │178 - try std.testing.expectEqualStrings("file-00.txt", file.fork_diff.path.slice()); │ │179 + try std.testing.expectEqualStrings("file-00.txt", file.fork_files.path.slice());│ │180 try std.testing.expectEqual(Diff.page_size, next.fork_diff.start); │ │181 } │ │182 } │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/try.zig│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────╮ │1082 base_oid: [hash.hexLen(.sha1)]u8, │ │1083 path: []const u8, │ │1084 contents: []const []const u8, │ │1085 + // a base file the last commit removes │ │1086 + removed_path: ?[]const u8, │ │1087 ) !void { │ │1088 const patch_hex = std.fmt.bytesToHex(patch_id.*, .lower); │ │1089 const fork_path = try fork.forkPath(allocator, users_dir, forker_id, patch_id);│ ╰─────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────╮ │1103 var writer = std.Io.Writer.Allocating.init(allocator); │ │1104 defer writer.deinit(); │ │1105 if (std.Io.Dir.path.dirname(path)) |dir| try fork_dir.createDirPath(io, dir);│ │1106 + const commit_count = contents.len + @intFromBool(removed_path != null); │ │1107 for (contents, 0..) |content, i| { │ │1108 { │ │1109 const file = try fork_dir.createFile(io, path, .{}); │ ╰───────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1112 } │ │1113 try fork_repo.add(io, allocator, &.{path}); │ │1114 writer.clearRetainingCapacity(); │ │1112 - try writer.writer.print("{s} ({d}/{d})", .{ title, i + 1, contents.len }); │ │1115 + try writer.writer.print("{s} ({d}/{d})", .{ title, i + 1, commit_count }); │ │1116 source_oid = try fork_repo.commit(io, allocator, .{ .message = writer.written(), .timestamp = timestamp + i }); │ │1117 } │ │1118 + if (removed_path) |removed| { │ │1119 + // the bare fork never checked the base files out, so only the index drops it │ │1120 + try fork_repo.remove(io, allocator, &.{removed}, .{ .update_work_dir = false }); │ │1121 + writer.clearRetainingCapacity(); │ │1122 + try writer.writer.print("{s} ({d}/{d})", .{ title, commit_count, commit_count }); │ │1123 + source_oid = try fork_repo.commit(io, allocator, .{ .message = writer.written(), .timestamp = timestamp + contents.len });│ │1124 + } │ │1125 try fork_repo.patchAll(io, allocator, null); │ │1126 try fork_repo.addConfig(io, allocator, .{ .name = "core.bare", .value = "true" }); │ │1127 try transaction(io, &fork_repo, Reindex{ .io = io, .allocator = allocator, .core = &fork_repo.core, .commits = false }); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────╮ │1181 alpha_edit: ?ScatterEdit = null, │ │1182 // based behind master, so merging it makes a merge commit│ │1183 behind_master: bool = false, │ │1184 + // a base file the patch removes │ │1185 + removed_path: ?[]const u8 = null, │ │1186 }{ │ │1187 .{ │ │1188 .title = "Draft a faster dependency scanner", │ ╰────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1208 .description = "Add a stable JSON representation of `inspect` results for scripts and editor integrations.",│ │1209 .labels = "enhancement cli", │ │1210 .status = .open, │ │1211 + .removed_path = "docs/dev/contribute.md", │ │1212 }, │ │1213 .{ │ │1214 .title = "Edit an adjacent line in alpha.txt", │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1280 } │ │1281 break :blk .{ "patch.txt", contents.len }; │ │1282 }; │ │1270 - try seedPatchRevision(io, allocator, users_dir, user_id, &patch_ids[i], patch.title, patch_author, timestamp + 1, random, base_oid, file_path, contents[0..count]); │ │1283 + try seedPatchRevision(io, allocator, users_dir, user_id, &patch_ids[i], patch.title, patch_author, timestamp + 1, random, base_oid, file_path, contents[0..count], patch.removed_path);│ │1284 } │ │1285 const status = patch.status orelse continue; │ │1286 try pch.publish(.{}, io, allocator, users_dir, admin_repo, target_repo, .{ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────╮ │src/ui/Fork.zig│ ╰───────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │165 .commits = commits, │ │166 .patch = patch_data, │ │167 .diff = .{ │ │168 - .route = .{ .fork = .{ .identity = try aa.dupe(u8, identity.identity), .id = try aa.dupe(u8, &id_hex), .oid = diff_oid, .base_oid = diff_base_oid } }, │ │168 + .route = .{ .fork = .{ .identity = try aa.dupe(u8, identity.identity), .id = try aa.dupe(u8, &id_hex), .oid = diff_oid, .base_oid = diff_base_oid, .patch_base_oid = try aa.dupe(u8, &commits_base_oid) } },│ │169 .path = diff_path, │ │170 .window = try Diff.render(.xit, repo_opts, io, arena.child_allocator, aa, fork_repo, if (diff_base) |*base| base else null, diff_head, diff_start, diff_path), │ │171 }, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯