╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ──────────────╮ │src/ui/Repo/Patches.zig│ ╰───────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │262 tags: []const u8, │ │263 description: []const u8, │ │264 target_branch: []const u8, │ │265 + source_branch: ?[]const u8, │ │266 ) ![evt.event_id_size * 2]u8 { │ │267 if (!evt.Patch.fieldsValid(title, tags)) return error.InvalidFields;│ │268 const io = session.io orelse return error.NotFound; │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │184 - const repos_dir = session.repos_dir orelse return error.NotFound; │ │185 - const admin_repo = session.admin_repo orelse return error.NotFound; │ │186 - const user_id = session.userId() orelse return error.NotFound; │ │187 - const repo_id = data.repo_id orelse return error.NotFound; │ │269 const repo_source = data.repo_source orelse return error.NotFound; │ │270 const author = (try session.eventAuthor()) orelse return error.NotFound; │ │190 - if (!try repo_source.hasBranch(io, allocator, target_branch)) return error.InvalidFields;│ │271 var id_bytes: [evt.event_id_size]u8 = undefined; │ │272 io.random(&id_bytes); │ │273 const id = std.fmt.bytesToHex(id_bytes, .lower); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │274 + if (source_branch) |branch| { │ │275 + switch (repo_source.repo_kind) { │ │276 + inline else => |repo_kind| { │ │277 + var any_repo = try rp.AnyRepo(repo_kind, .{}).open(io, allocator, repo_source.localInitOpts()); │ │278 + defer any_repo.deinit(io, allocator); │ │279 + switch (any_repo) { │ │280 + inline else => |*repo| try pch.writeBranchPatch(session.data.host_kind, repo_kind, repo.self_repo_opts, io, allocator, repo, id, .{│ │281 + .title = title, │ │282 + .tags = tags, │ │283 + .description = description, │ │284 + .target_branch = target_branch, │ │285 + .source_branch = branch, │ │286 + }, null, author), │ │287 + } │ │288 + }, │ │289 + } │ │290 + return id; │ │291 + } │ │292 + if (session.data.host_kind == .local) return error.InvalidSourceBranch; │ │293 + const repos_dir = session.repos_dir orelse return error.NotFound; │ │294 + const admin_repo = session.admin_repo orelse return error.NotFound; │ │295 + const user_id = session.userId() orelse return error.NotFound; │ │296 + const repo_id = data.repo_id orelse return error.NotFound; │ │297 + if (!try repo_source.hasBranch(io, allocator, target_branch)) return error.InvalidTargetBranch; │ │298 const fork_path = try fork.create(.{}, io, allocator, repos_dir, admin_repo, .{ │ │299 .id = id, │ │300 .user_id = user_id, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │373 const user_id = session.userId() orelse return error.NotFound; │ │374 const patch_id = evt.parseEventId(id) catch return error.NotFound; │ │375 const author = (try session.eventAuthor()) orelse return error.NotFound; │ │272 - if (!try repo_source.hasBranch(io, allocator, target_branch)) return error.InvalidFields; │ │376 + if (!try repo_source.hasBranch(io, allocator, target_branch)) return error.InvalidTargetBranch;│ │377 │ │378 const id_hex = std.fmt.bytesToHex(patch_id, .lower); │ │379 const fork_path = try fork.forkPath(allocator, repos_dir, &id_hex); │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │505 theirs_picks: []const u8, │ │506 view: ui.RoutablePage.PatchesView, │ │507 ) !Self { │ │404 - const allowed_view: ui.RoutablePage.PatchesView = if (session.local != null and (view == .new or view == .drafts)) .open else view;│ │508 + const allowed_view: ui.RoutablePage.PatchesView = if (session.local != null and view == .drafts) .open else view; │ │509 var empty = try emptyResult(arena.allocator(), identity, tag, selected_id, comment_id, comments_start, theirs_picks, allowed_view);│ │510 empty.default_target_branch = try arena.allocator().dupe(u8, target_branch); │ │511 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │650 var closed_window = try thread.loadWindow(Self, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_patch, closed_set, closed_root, conflict_set, empty.selected_id, thread_comments_start); │ │651 var merged_window = try thread.loadWindow(Self, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_patch, merged_set, merged_root, conflict_set, empty.selected_id, thread_comments_start); │ │652 var conflicts_window = try thread.loadWindow(Self, repo_opts.hash, arena, admin_moment, haxy_moment, event_id_to_patch, conflict_set, conflicts_root, conflict_set, empty.selected_id, thread_comments_start);│ │549 - try setForkDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &open_window); │ │550 - try setForkDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &closed_window); │ │551 - try setForkDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &merged_window); │ │552 - try setForkDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &conflicts_window); │ │653 + try setPatchDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &open_window); │ │654 + try setPatchDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &closed_window); │ │655 + try setPatchDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &merged_window); │ │656 + try setPatchDetails(repo_kind, repo_opts, io, arena, admin_moment, repo, &conflicts_window); │ │657 if (view == .conflicts and conflicts_window.count > 0) resolved_view = .conflicts; │ │658 │ │659 const comment_page = if (empty.comment_id.len == 0) │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────╮ │684 }; │ │685 } │ │686 │ │583 -fn setForkDetails( │ │687 +fn setPatchDetails( │ │688 comptime repo_kind: rp.RepoKind, │ │689 comptime repo_opts: rp.RepoOpts(repo_kind),│ │690 io: std.Io, │ ╰────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────╮ │703 } │ │704 const target_branch = item.record.event.target_branch; │ │705 const revision = item.record.event.revision orelse continue;│ │602 - item.fork_oid = switch (item.record.event.status) { │ │706 + item.revision_oid = switch (item.record.event.status) { │ │707 .merged => |oid| oid, │ │708 else => revision.source_oid, │ │709 }; │ ╰─────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────╮ │813 .record = patch, │ │814 .author = try ui.Author.initFromEmail(admin_moment, arena, patch.author_email), │ │815 .draft = true, │ │712 - .fork_oid = try aa.dupe(u8, &fork_oid), │ │816 + .revision_oid = try aa.dupe(u8, &fork_oid), │ │817 .no_changes = if (target_oid) |oid| std.mem.eql(u8, &oid, &fork_oid) else false,│ │818 .fork_exists = true, │ │819 }; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │829 const aa = session.page_arena.allocator(); │ │830 const status_kind = entry.record.event.status.kind(); │ │831 const target_branch = entry.record.event.target_branch; │ │728 - var fields: [2]ui.widget.CopyableText.Choice = undefined; │ │729 - var field_count: usize = 0; │ │832 │ │833 if (status_kind != .merged and entry.fork_exists) if (session.data.git_ssh_port) |port| { │ │834 const url = try std.fmt.allocPrint(aa, "ssh://localhost:{d}/fork/{s}/patch:{s}", .{ port, self.identity, entry.id });│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯