| ... | ... | @@ -46,6 +46,10 @@ pub const Diagnostics = struct { |
| 46 | 46 | file_name: []const u8, |
| 47 | 47 | link_name: []const u8, |
| 48 | 48 | }, |
| 49 | unable_to_create_file: struct { |
| 50 | code: anyerror, |
| 51 | file_name: []const u8, |
| 52 | }, |
| 49 | 53 | }; |
| 50 | 54 | |
| 51 | 55 | pub fn deinit(d: *Diagnostics) void { |
| ... | ... | @@ -55,6 +59,9 @@ pub const Diagnostics = struct { |
| 55 | 59 | d.allocator.free(info.file_name); |
| 56 | 60 | d.allocator.free(info.link_name); |
| 57 | 61 | }, |
| 62 | .unable_to_create_file => |info| { |
| 63 | d.allocator.free(info.file_name); |
| 64 | }, |
| 58 | 65 | } |
| 59 | 66 | } |
| 60 | 67 | d.errors.deinit(d.allocator); |
| ... | ... | @@ -119,11 +126,19 @@ pub const Repository = struct { |
| 119 | 126 | try repository.checkoutTree(subdir, entry.oid, sub_path, diagnostics); |
| 120 | 127 | }, |
| 121 | 128 | .file => { |
| 122 | | var file = try dir.createFile(entry.name, .{}); |
| 123 | | defer file.close(); |
| 124 | 129 | try repository.odb.seekOid(entry.oid); |
| 125 | 130 | const file_object = try repository.odb.readObject(); |
| 126 | 131 | if (file_object.type != .blob) return error.InvalidFile; |
| 132 | var file = dir.createFile(entry.name, .{ .exclusive = true }) catch |e| { |
| 133 | const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name }); |
| 134 | errdefer diagnostics.allocator.free(file_name); |
| 135 | try diagnostics.errors.append(diagnostics.allocator, .{ .unable_to_create_file = .{ |
| 136 | .code = e, |
| 137 | .file_name = file_name, |
| 138 | } }); |
| 139 | continue; |
| 140 | }; |
| 141 | defer file.close(); |
| 127 | 142 | try file.writeAll(file_object.data); |
| 128 | 143 | try file.sync(); |
| 129 | 144 | }, |