fetch.git: collect file create diagnostic errors

On case insensitive file systems, don't overwrite files with same name
in different casing. Add diagnostic error so caller could decide what to do.
This commit is contained in:
Igor Anić 2024-03-30 22:43:27 +01:00
parent ad60b6c1ed
commit 5a38924a7d
2 changed files with 18 additions and 2 deletions

View File

@ -1249,6 +1249,7 @@ fn unpackGitPack(f: *Fetch, out_dir: fs.Dir, resource: *Resource) anyerror!Unpac
try res.rootErrorMessage("unable to unpack packfile");
for (diagnostics.errors.items) |item| {
switch (item) {
.unable_to_create_file => |i| try res.unableToCreateFile(i.file_name, i.code),
.unable_to_create_sym_link => |i| try res.unableToCreateSymLink(i.file_name, i.link_name, i.code),
}
}

View File

@ -46,6 +46,10 @@ pub const Diagnostics = struct {
file_name: []const u8,
link_name: []const u8,
},
unable_to_create_file: struct {
code: anyerror,
file_name: []const u8,
},
};
pub fn deinit(d: *Diagnostics) void {
@ -55,6 +59,9 @@ pub const Diagnostics = struct {
d.allocator.free(info.file_name);
d.allocator.free(info.link_name);
},
.unable_to_create_file => |info| {
d.allocator.free(info.file_name);
},
}
}
d.errors.deinit(d.allocator);
@ -119,11 +126,19 @@ pub const Repository = struct {
try repository.checkoutTree(subdir, entry.oid, sub_path, diagnostics);
},
.file => {
var file = try dir.createFile(entry.name, .{});
defer file.close();
try repository.odb.seekOid(entry.oid);
const file_object = try repository.odb.readObject();
if (file_object.type != .blob) return error.InvalidFile;
var file = dir.createFile(entry.name, .{ .exclusive = true }) catch |e| {
const file_name = try std.fs.path.join(diagnostics.allocator, &.{ current_path, entry.name });
errdefer diagnostics.allocator.free(file_name);
try diagnostics.errors.append(diagnostics.allocator, .{ .unable_to_create_file = .{
.code = e,
.file_name = file_name,
} });
continue;
};
defer file.close();
try file.writeAll(file_object.data);
try file.sync();
},