╭ changed ────╮ │src/serve.zig│ ╰─────────────╯ ╭───────────────────────────────────────────────────╮ │13 ssh_listen: ?[]const u8 = "127.0.0.1:8022",│ │14 wui_listen: []const u8 = "127.0.0.1:8000", │ │15 data_dir: []const u8 = ".", │ │16 + git_ssh_prefix: []const u8 = "", │ │17 }; │ │18 │ │19 const ListenAddress = struct { │ ╰───────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │105 .wui_port = wui_server.socket.address.getPort(),│ │106 .git_http_port = git_http_port, │ │107 .git_ssh_port = ssh_port, │ │108 + .git_ssh_prefix = options.git_ssh_prefix, │ │109 .err = err, │ │110 }, │ │111 }; │ ╰─────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────╮ │141 .session_store = session_store, │ │142 .git_http_port = git_http_port, │ │143 .git_ssh_port = git_ssh_port, │ │144 + .git_ssh_prefix = options.git_ssh_prefix,│ │145 } }, err); │ │146 │ │147 if (@TypeOf(runnable) != void) { │ ╰──────────────────────────────────────────────────────╯ ╭ changed ────────╮ │src/serve_ssh.zig│ ╰─────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │29 wui_port: u16, // port the web UI is served on, shown in the TUI footer's url │ │30 git_http_port: ?u16, │ │31 git_ssh_port: ?u16, │ │32 + git_ssh_prefix: []const u8, │ │33 err: *std.Io.Writer, │ │34 │ │35 pub fn handleSession(self: *const SessionHandler, sess: *ssh.SessionCtx, request: ssh.Request) !void {│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │200 ui_session.web_port = handler.wui_port; │ │201 ui_session.data.git_http_port = handler.git_http_port; │ │202 ui_session.data.git_ssh_port = handler.git_ssh_port; │ │203 + ui_session.data.git_ssh_prefix = handler.git_ssh_prefix; │ │204 // let page builders open on-disk repos (sibling "repos" dir of the admin repo) │ │205 ui_session.io = io; │ │206 ui_session.repos_dir = try std.fs.path.join(session_arena.allocator(), &.{ std.fs.path.dirname(handler.admin_repo_path) orelse ".", "repos" });│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────╮ │src/test/net.zig│ ╰────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │628 const moment = try evt.currentMoment(.{}, &draft); │ │629 const patch = (try evt.Patch.readById(evt.EventDB(.sha1), .sha1, moment, &arena, &fork_id)) orelse return error.NotFound; │ │630 try std.testing.expect(!patch.removed); │ │631 - first_revision_id = try evt.parseEventId(&(patch.event.revision orelse return error.NotFound).id); │ │631 + try std.testing.expectEqualStrings(&source_oid, &(try draft.readRef(io, fork.ref) orelse return error.NotFound)); │ │632 + const selected = patch.event.revision orelse return error.NotFound; │ │633 + try std.testing.expectEqualStrings("refs/heads/master", selected.target_ref); │ │634 + try std.testing.expectEqualStrings(&source_oid, selected.source_oid); │ │635 + first_revision_id = try evt.parseEventId(&selected.id); │ │636 const revision = (try evt.PatchRev.readById(evt.EventDB(.sha1), .sha1, moment, &arena, &first_revision_id)) orelse return error.NotFound;│ │637 try std.testing.expectEqualStrings("refs/heads/master", revision.event.target_ref); │ │638 try std.testing.expectEqualStrings(&source_oid, revision.event.source_oid); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────╮ │647 defer admin.deinit(io, allocator); │ │648 var target = try rp.Repo(.xit, .{}).open(io, allocator, .{ .path = target_path });│ │649 defer target.deinit(io, allocator); │ │650 + try target.addBranch(io, .{ .name = "feature" }); │ │651 try pch.post(.{}, io, allocator, &admin, &target, draft_path, .{ │ │652 .id = fork_id_hex, │ │653 .user_id = user_id, │ ╰───────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │673 }}); │ │674 } │ │675 │ │676 + const feature_remote_url = try std.fmt.allocPrint(allocator, "git@localhost:admin/target/patch:{s}/branch:feature", .{&fork_id_hex});│ │677 + defer allocator.free(feature_remote_url); │ │678 + try client.addRemote(io, allocator, .{ .name = "patch-to-feature", .value = feature_remote_url }); │ │679 + │ │680 const second_source_oid = blk: { │ │681 const file = try client.core.work_dir.createFile(io, "feature.txt", .{ .truncate = true }); │ │682 defer file.close(io); │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │684 try client.add(io, allocator, &.{"feature.txt"}); │ │685 break :blk try client.commit(io, allocator, .{ .message = "revise feature" }); │ │686 }; │ │678 - try client.push(io, allocator, "patch", "master:patch", false, .{ .wire = .{ .ssh = .{ .command = ssh_cmd } } }); │ │687 + try client.push(io, allocator, "patch-to-feature", "master:patch", false, .{ .wire = .{ .ssh = .{ .command = ssh_cmd } } });│ │688 │ │689 var second_revision_id: [evt.event_id_size]u8 = undefined; │ │690 var second_patch_oid: [hash.hexLen(.sha1)]u8 = undefined; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────╮ │701 @memcpy(&second_patch_oid, newest.record.patch_oid); │ │702 try std.testing.expect(!std.mem.eql(u8, &first_revision_id, &second_revision_id)); │ │703 try std.testing.expectEqualStrings(&second_source_oid, newest.record.event.source_oid); │ │704 + try std.testing.expectEqualStrings("refs/heads/feature", newest.record.event.target_ref);│ │705 try std.testing.expectEqualStrings("edited feature", newest.record.event.message); │ │706 } │ │707 { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯