╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ───╮ │src/fork.zig│ ╰────────────╯ ╭────────────────────────────────────────╮ │382 .allocator = allocator,│ │383 .reader = reader, │ │384 .writer = writer, │ │385 + .response = &response, │ │386 .patch_id = id.*, │ │387 .patch = fork_patch, │ │388 .published = published,│ ╰────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │392 .timestamp = timestamp, │ │393 .newest = newest, │ │394 .revision_id_maybe = &revision_id_maybe, │ │390 - }) catch |err| switch (err) { │ │391 - error.CancelTransaction => {}, │ │392 - else => |other| return other, │ │395 + }) catch |err| { │ │396 + response.finish(writer, @errorName(err)) catch {}; │ │397 + if (err == error.CancelTransaction) return; │ │398 + return err; │ │399 }; │ │394 - try writer.flush(); │ │400 + try response.finish(writer, null); │ │401 } │ │402 │ │403 // best-effort update the published patch so it has the new revision│ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────╮ │src/patch.zig│ ╰─────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │253 { │ │254 var merge_result = try mrg.Merge(.xit, repo_opts).init(state, ctx.io, ctx.allocator, .{ │ │255 .kind = .full, │ │256 - .action = .{ .new = .{ .source = &.{.{ .oid = &ctx.merge_oid }}, .algo = .diff3 } },│ │256 + .action = .{ .new = .{ .source = &.{.{ .oid = &ctx.merge_oid }}, .algo = .patch } },│ │257 .commit_metadata = .{ │ │258 .author = ctx.identity, │ │259 .committer = ctx.identity, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/serve_ssh.zig│ ╰─────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │359 │ │360 const draft_path = try fork.forkPath(allocator, handler.repo_root_path, &route.id); │ │361 defer allocator.free(draft_path); │ │362 - var draft = rp.AnyRepo(.xit, .{}).open(io, allocator, .{ .path = draft_path }) catch │ │362 + var draft = rp.AnyRepo(.xit, .{ .ProgressCtx = *evt.PushProgress }).open(io, allocator, .{ .path = draft_path }) catch│ │363 return writeError(sess, "patch draft not found"); │ │364 defer draft.deinit(io, allocator); │ │365 var reader_buf: [4096]u8 = undefined; │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │397 const repo_identity = if (std.mem.startsWith(u8, path, repo_prefix)) path[repo_prefix.len..] else path; │ │398 │ │399 const create_if_missing = parsed.service == .receive_pack; │ │400 - const any_repo_opts: rp.AnyRepoOpts(.xit) = .{}; │ │400 + const any_repo_opts: rp.AnyRepoOpts(.xit) = .{ .ProgressCtx = *evt.PushProgress }; │ │401 │ │402 const owner_repo = evt.parseOwnerRepoPath(repo_identity) orelse return writeError(sess, "repo path must be <owner>/<repo>"); │ │403 switch (try authorizeRepoKey(io, allocator, handler.admin_repo_path, owner_repo.owner, owner_repo.name, parsed.service, &sess.fingerprint)) {│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │444 // attempt it when the path already exists │ │445 std.Io.Dir.accessAbsolute(io, repo_path, .{}) catch return false; │ │446 │ │447 - const any_repo_opts: rp.AnyRepoOpts(.xit) = .{}; │ │447 + const any_repo_opts: rp.AnyRepoOpts(.xit) = .{ .ProgressCtx = *evt.PushProgress }; │ │448 var any_repo = rp.AnyRepo(.xit, any_repo_opts).open(io, allocator, .{ .path = repo_path }) catch |err| switch (err) {│ │449 error.RepoNotFound => return false, │ │450 else => |e| return e, │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │465 ) !rp.Repo(.xit, repo_opts) { │ │466 var repo = try rp.Repo(.xit, repo_opts).init(io, allocator, .{ .path = repo_path, .bare = true });│ │467 errdefer repo.deinit(io, allocator); │ │468 - try repo.setMergeAlgorithm(io, allocator, .diff3); │ │468 + try repo.setMergeAlgorithm(io, allocator, .patch); │ │469 try repo.addConfig(io, allocator, .{ .name = "http.receivepack", .value = "true" }); │ │470 return repo; │ │471 } │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──╮ │src/try.zig│ ╰───────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │253 var template_repo = try rp.Repo(.xit, .{}).init(io, allocator, .{ .path = template_path }); │ │254 defer template_repo.deinit(io, allocator); │ │255 │ │256 - try template_repo.setMergeAlgorithm(io, allocator, .diff3); │ │256 + try template_repo.setMergeAlgorithm(io, allocator, .patch); │ │257 try template_repo.addConfig(io, allocator, .{ .name = "user.name", .value = "haxy" }); │ │258 try template_repo.addConfig(io, allocator, .{ .name = "user.email", .value = "admin@example.test" });│ │259 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Commits.zig│ ╰───────────────────────╯ ╭───────────────────────────────────────────────────────────────────────╮ │36 // whether `message` is a shortened preview. │ │37 message_truncated: bool = false, │ │38 author: ui.Author = .unknown, │ │39 + stats: ?xit.patch.CommitStats = null, │ │40 hunks: []const Hunk, │ │41 // the hunk index this window starts at (0 = the first window).│ │42 window_start: usize, │ ╰───────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │145 .message = text, │ │146 .message_truncated = truncated, │ │147 .author = try ui.Author.init(admin_moment, arena, md.author orelse ""), │ │148 + .stats = if (repo_kind == .xit) try repo.commitStats(io, gpa, .{ .oid = &commit_object.oid }) else null,│ │149 .hunks = &.{}, │ │150 .window_start = 0, │ │151 .has_prev = false, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯