╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ test.zig ─────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
1798 try client_repo.add(io, allocator, &.{dir_name}); 1799 } 1800 1801 const commit2 = try client_repo.commit(io, allocator, .{ .message = "more stuff" }); 1802 1803 // add remote 1804 { 1805 if (.windows == builtin.os.tag) { 1806 std.mem.replaceScalar(u8, server_path, '\\', '/'); 1807 } 1808 const separator = if (server_path[0] == '/') "" else "/"; 1809 1810 const remote_url = switch (transport_def) { 1811 //.file => try std.fmt.allocPrint(allocator, "file://{s}{s}", .{ separator, server_path }), 1812 .file => try std.fmt.allocPrint(allocator, "../server", .{}), // relative file paths work too 1813 .wire => |wire_kind| switch (wire_kind) { 1814 .http => try std.fmt.allocPrint(allocator, "http://localhost:{}/server", .{port}), 1815 .raw => try std.fmt.allocPrint(allocator, "git://localhost:{}/server", .{port}), 1816 .ssh => try std.fmt.allocPrint(allocator, "ssh://localhost:{}{s}{s}", .{ port, separator, server_path }), 1817 }, 1818 }; 1819 defer allocator.free(remote_url); 1820 1821 try client_repo.addRemote(io, allocator, .{ .name = "origin", .value = remote_url }); 1822 try client_repo.addConfig(io, allocator, .{ .name = "branch.master.remote", .value = "origin" }); 1823 } 1824 1825 const is_ssh = switch (transport_def) { 1826 .file => false, 1827 .wire => |wire_kind| .ssh == wire_kind, 1828 }; 1829 1830 const receive_pack_command = try receivePackCommand(server_repo_kind, is_ssh, use_serve_command, allocator, cwd_path, port); 1831 defer allocator.free(receive_pack_command); 1832 1833 if (shell_out_to_git) { 1834 const priv_key_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "key" }); 1835 defer allocator.free(priv_key_path); 1836 const ssh_config_arg = try std.fmt.allocPrint(allocator, "core.sshCommand=ssh -o StrictHostKeyChecking=no -o IdentityFile={s}", .{priv_key_path}); 1837 defer allocator.free(ssh_config_arg); 1838 1839 // shell out to git so it will send delta objects 1840 var process = try std.process.spawn(io, .{ 1841 .argv = if (is_ssh) 1842 &.{ "git", "-c", ssh_config_arg, "push", "--receive-pack", receive_pack_command, "origin", "master" } 1843 else 1844 &.{ "git", "push", "origin", "master" }, 1845 .cwd = .{ .path = client_path }, 1846 .stdin = .ignore, 1847 .stdout = .ignore, 1848 .stderr = .ignore, 1849 }); 1850 const term = try process.wait(io); 1851 if (term != .exited) { 1852 return error.GitCommandFailed; 1853 } 1854 } else { 1855 const ssh_cmd_maybe: ?[]const u8 = if (is_ssh) blk: { 1856 const known_hosts_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "known_hosts" }); 1857 defer allocator.free(known_hosts_path); 1858 1859 const priv_key_path = try std.fs.path.join(allocator, &.{ cwd_path, temp_dir_name, "key" }); 1860 defer allocator.free(priv_key_path); 1861 1862 break :blk try std.fmt.allocPrint(allocator, "ssh -o UserKnownHostsFile=\"{s}\" -o IdentityFile=\"{s}\"", .{ known_hosts_path, priv_key_path }); 1863 } else null; 1864 defer if (ssh_cmd_maybe) |ssh_cmd| allocator.free(ssh_cmd); 1865 1866 try client_repo.push( 1867 io, 1868 allocator, 1869 "origin", 1870 "master", 1871 false, 1872 .{ .wire = .{ .ssh = .{ 1873 .command = ssh_cmd_maybe, 1874 .receive_pack_command = receive_pack_command, 1875 } } }, 1876 ); 1877 1878 if (transport_def == .file) { 1879 // update the working dir 1880 try server_repo.restore(io, allocator, "."); 1881 } 1882 } 1883 1884 // make sure push was successful 1885 { 1886 const oid_master = (try server_repo.readRef(io, .{ .kind = .head, .name = "master" })).?; 1887 try std.testing.expectEqualStrings(&commit2, &oid_master); 1888 1889 const hello_txt = try temp_dir.openFile(io, "server/hello.txt", .{}); 1890 defer hello_txt.close(io); 1891 } 1892 } 1893 1894 fn copyDir(io: std.Io, src_dir: std.Io.Dir, dest_dir: std.Io.Dir) !void { 1895 var iter = src_dir.iterate(); 1896 while (try iter.next(io)) |entry| { 1897 switch (entry.kind) { 1898 .file => try src_dir.copyFile(entry.name, dest_dir, entry.name, io, .{}), 1899 .directory => { 1900 try dest_dir.createDirPath(io, entry.name); 1901 var dest_entry_dir = try dest_dir.openDir(io, entry.name, .{ .access_sub_paths = true, .iterate = true, .follow_symlinks = false }); 1902 defer dest_entry_dir.close(io); 1903 var src_entry_dir = try src_dir.openDir(io, entry.name, .{ .access_sub_paths = true, .iterate = true, .follow_symlinks = false }); 1904 defer src_entry_dir.close(io); 1905 try copyDir(io, src_entry_dir, dest_entry_dir); 1906 }, 1907 else => {}, 1908 } 1909 } 1910 } 1911