| ... | ... | @@ -41,6 +41,26 @@ pub const TagId = struct { |
| 41 | 41 | } |
| 42 | 42 | }; |
| 43 | 43 | |
| 44 | pub const OidKind = enum { |
| 45 | blob, |
| 46 | tree, |
| 47 | commit, |
| 48 | tag, |
| 49 | }; |
| 50 | |
| 51 | pub const AnyId = union(OidKind) { |
| 52 | blob: BlobId, |
| 53 | tree: TreeId, |
| 54 | commit: CommitId, |
| 55 | tag: TagId, |
| 56 | |
| 57 | pub fn erase(self: AnyId) Id { |
| 58 | return switch (self) { |
| 59 | inline else => |v| v.id, |
| 60 | }; |
| 61 | } |
| 62 | }; |
| 63 | |
| 44 | 64 | pub fn version(alloc: std.mem.Allocator) !string { |
| 45 | 65 | const result = try std.process.Child.run(.{ |
| 46 | 66 | .allocator = alloc, |
| ... | ... | @@ -139,7 +159,7 @@ pub fn getObjectSize(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !u64 { |
| 139 | 159 | // TODO make this inspect .git manually |
| 140 | 160 | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 141 | 161 | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 142 | | pub fn isType(alloc: std.mem.Allocator, dir: nfs.Dir, maybeobj: Id, typ: Tree.Object.Id.Tag) !bool { |
| 162 | pub fn isType(alloc: std.mem.Allocator, dir: nfs.Dir, maybeobj: Id, typ: OidKind) !bool { |
| 143 | 163 | const t = tracer.trace(@src(), " {s} = {s} ?", .{ maybeobj, @tagName(typ) }); |
| 144 | 164 | defer t.end(); |
| 145 | 165 | |
| ... | ... | @@ -150,13 +170,13 @@ pub fn isType(alloc: std.mem.Allocator, dir: nfs.Dir, maybeobj: Id, typ: Tree.Ob |
| 150 | 170 | }); |
| 151 | 171 | std.debug.assert(result.term == .Exited and result.term.Exited == 0); |
| 152 | 172 | const output = std.mem.trimRight(u8, result.stdout, "\n"); |
| 153 | | return std.meta.stringToEnum(Tree.Object.Id.Tag, output).? == typ; |
| 173 | return std.meta.stringToEnum(OidKind, output).? == typ; |
| 154 | 174 | } |
| 155 | 175 | |
| 156 | 176 | // TODO make this inspect .git manually |
| 157 | 177 | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 158 | 178 | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 159 | | pub fn getType(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !Tree.Object.Id.Tag { |
| 179 | pub fn getType(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !OidKind { |
| 160 | 180 | const t = tracer.trace(@src(), " {s}", .{obj}); |
| 161 | 181 | defer t.end(); |
| 162 | 182 | |
| ... | ... | @@ -167,7 +187,7 @@ pub fn getType(alloc: std.mem.Allocator, dir: nfs.Dir, obj: Id) !Tree.Object.Id. |
| 167 | 187 | }); |
| 168 | 188 | std.debug.assert(result.term == .Exited and result.term.Exited == 0); |
| 169 | 189 | const output = std.mem.trimRight(u8, result.stdout, "\n"); |
| 170 | | return std.meta.stringToEnum(Tree.Object.Id.Tag, output) orelse @panic(output); |
| 190 | return std.meta.stringToEnum(OidKind, output) orelse @panic(output); |
| 171 | 191 | } |
| 172 | 192 | |
| 173 | 193 | // TODO make this inspect .git/objects manually |
| ... | ... | @@ -311,18 +331,18 @@ pub fn parseTree(alloc: std.mem.Allocator, treefile: string) !Tree { |
| 311 | 331 | } |
| 312 | 332 | var jter = std.mem.splitScalar(u8, line, ' '); |
| 313 | 333 | const mode = jter.next().?; |
| 314 | | const otype = std.meta.stringToEnum(Tree.Object.Id.Tag, jter.next().?).?; |
| 334 | const otype = std.meta.stringToEnum(OidKind, jter.next().?).?; |
| 315 | 335 | const id_and_name = jter.rest(); |
| 316 | 336 | const tab_pos = std.mem.indexOfScalar(u8, id_and_name, '\t').?; // why git. why. |
| 317 | 337 | std.debug.assert(tab_pos == 40); |
| 318 | 338 | const id = id_and_name[0..tab_pos][0..40]; |
| 319 | 339 | const name = id_and_name[tab_pos + 1 ..]; |
| 320 | 340 | |
| 321 | | inline for (std.meta.fields(Tree.Object.Id)) |item| { |
| 341 | inline for (std.meta.fields(AnyId)) |item| { |
| 322 | 342 | if (std.mem.eql(u8, item.name, @tagName(otype))) { |
| 323 | 343 | try children.append(.{ |
| 324 | 344 | .mode = try parseTreeMode(mode), |
| 325 | | .id = @unionInit(Tree.Object.Id, item.name, item.type{ .id = id }), |
| 345 | .id = @unionInit(AnyId, item.name, item.type{ .id = id }), |
| 326 | 346 | .name = name, |
| 327 | 347 | }); |
| 328 | 348 | } |
| ... | ... | @@ -381,24 +401,9 @@ pub const Tree = struct { |
| 381 | 401 | |
| 382 | 402 | pub const Object = struct { |
| 383 | 403 | mode: Mode, |
| 384 | | id: @This().Id, |
| 404 | id: AnyId, |
| 385 | 405 | name: string, |
| 386 | 406 | |
| 387 | | pub const Id = union(enum) { |
| 388 | | blob: BlobId, |
| 389 | | tree: TreeId, |
| 390 | | commit: CommitId, |
| 391 | | tag: TagId, |
| 392 | | |
| 393 | | pub const Tag = std.meta.Tag(@This()); |
| 394 | | |
| 395 | | pub fn erase(self: @This()) top.Id { |
| 396 | | return switch (self) { |
| 397 | | inline else => |v| v.id, |
| 398 | | }; |
| 399 | | } |
| 400 | | }; |
| 401 | | |
| 402 | 407 | pub const Mode = struct { |
| 403 | 408 | type: Type, |
| 404 | 409 | perm_user: Perm, |