| ... | ... | @@ -122,74 +122,6 @@ pub fn ensureObjId(comptime T: type, input: string) T { |
| 122 | 122 | return .{ .id = input[0..40] }; |
| 123 | 123 | } |
| 124 | 124 | |
| 125 | | // TODO make this inspect .git/objects |
| 126 | | // TODO make this return a Reader when we implement it ourselves |
| 127 | | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 128 | | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 129 | | pub fn getObjectContent(alloc: std.mem.Allocator, dir: nfs.Dir, oid: Id) !string { |
| 130 | | const t = tracer.trace(@src(), " {s}", .{oid}); |
| 131 | | defer t.end(); |
| 132 | | |
| 133 | | const result = try std.process.Child.run(.{ |
| 134 | | .allocator = alloc, |
| 135 | | .cwd_dir = dir.to_std(), |
| 136 | | .argv = &.{ "git", "cat-file", "-p", oid }, |
| 137 | | .max_output_bytes = 1024 * 1024 * 1024, |
| 138 | | }); |
| 139 | | extras.assertLog(result.term == .Exited and result.term.Exited == 0, "{s}", .{result.stderr}); |
| 140 | | return result.stdout; |
| 141 | | } |
| 142 | | |
| 143 | | // TODO make this inspect .git/objects manually |
| 144 | | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 145 | | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 146 | | pub fn getObjectSize(alloc: std.mem.Allocator, dir: nfs.Dir, oid: Id) !u64 { |
| 147 | | const t = tracer.trace(@src(), " {s}", .{oid}); |
| 148 | | defer t.end(); |
| 149 | | |
| 150 | | const result = try std.process.Child.run(.{ |
| 151 | | .allocator = alloc, |
| 152 | | .cwd_dir = dir.to_std(), |
| 153 | | .argv = &.{ "git", "cat-file", "-s", oid }, |
| 154 | | }); |
| 155 | | extras.assertLog(result.term == .Exited and result.term.Exited == 0, "{s}", .{result.stderr}); |
| 156 | | return try extras.parseDigits(u64, std.mem.trimRight(u8, result.stdout, "\n"), 10); |
| 157 | | } |
| 158 | | |
| 159 | | // TODO make this inspect .git manually |
| 160 | | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 161 | | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 162 | | pub fn isType(alloc: std.mem.Allocator, dir: nfs.Dir, maybeoid: Id, typ: RefType) !bool { |
| 163 | | const t = tracer.trace(@src(), " {s} = {s} ?", .{ maybeoid, @tagName(typ) }); |
| 164 | | defer t.end(); |
| 165 | | |
| 166 | | const result = try std.process.Child.run(.{ |
| 167 | | .allocator = alloc, |
| 168 | | .cwd_dir = dir.to_std(), |
| 169 | | .argv = &.{ "git", "cat-file", "-t", maybeoid }, |
| 170 | | }); |
| 171 | | std.debug.assert(result.term == .Exited and result.term.Exited == 0); |
| 172 | | const output = std.mem.trimRight(u8, result.stdout, "\n"); |
| 173 | | return std.meta.stringToEnum(RefType, output).? == typ; |
| 174 | | } |
| 175 | | |
| 176 | | // TODO make this inspect .git manually |
| 177 | | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 178 | | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 179 | | pub fn getType(alloc: std.mem.Allocator, dir: nfs.Dir, oid: Id) !RefType { |
| 180 | | const t = tracer.trace(@src(), " {s}", .{oid}); |
| 181 | | defer t.end(); |
| 182 | | |
| 183 | | const result = try std.process.Child.run(.{ |
| 184 | | .allocator = alloc, |
| 185 | | .cwd_dir = dir.to_std(), |
| 186 | | .argv = &.{ "git", "cat-file", "-t", oid }, |
| 187 | | }); |
| 188 | | std.debug.assert(result.term == .Exited and result.term.Exited == 0); |
| 189 | | const output = std.mem.trimRight(u8, result.stdout, "\n"); |
| 190 | | return std.meta.stringToEnum(RefType, output) orelse @panic(output); |
| 191 | | } |
| 192 | | |
| 193 | 125 | // TODO make this inspect .git/objects manually |
| 194 | 126 | // TODO make a version of this that accepts an array of sub_paths and searches all of them at once, so as to not lose spot in history when searching for many old paths |
| 195 | 127 | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| ... | ... | @@ -316,43 +248,6 @@ pub const UserAndAt = struct { |
| 316 | 248 | at: time.DateTime, |
| 317 | 249 | }; |
| 318 | 250 | |
| 319 | | pub fn parseTree(alloc: std.mem.Allocator, treefile: string) !Tree { |
| 320 | | const t = tracer.trace(@src(), "", .{}); |
| 321 | | defer t.end(); |
| 322 | | |
| 323 | | var iter = std.mem.splitScalar(u8, treefile, '\n'); |
| 324 | | var children = std.ArrayList(Tree.Object).init(alloc); |
| 325 | | errdefer children.deinit(); |
| 326 | | |
| 327 | | while (iter.next()) |line| { |
| 328 | | if (line.len == 0) { |
| 329 | | std.debug.assert(iter.peek() == null); |
| 330 | | break; |
| 331 | | } |
| 332 | | var jter = std.mem.splitScalar(u8, line, ' '); |
| 333 | | const mode = jter.next().?; |
| 334 | | const otype = std.meta.stringToEnum(RefType, jter.next().?).?; |
| 335 | | const id_and_name = jter.rest(); |
| 336 | | const tab_pos = std.mem.indexOfScalar(u8, id_and_name, '\t').?; // why git. why. |
| 337 | | std.debug.assert(tab_pos == 40); |
| 338 | | const id = id_and_name[0..tab_pos][0..40]; |
| 339 | | const name = id_and_name[tab_pos + 1 ..]; |
| 340 | | |
| 341 | | inline for (std.meta.fields(AnyId)) |item| { |
| 342 | | if (std.mem.eql(u8, item.name, @tagName(otype))) { |
| 343 | | try children.append(.{ |
| 344 | | .mode = try parseTreeMode(mode), |
| 345 | | .id = @unionInit(AnyId, item.name, item.type{ .id = id }), |
| 346 | | .name = name, |
| 347 | | }); |
| 348 | | } |
| 349 | | } |
| 350 | | } |
| 351 | | return Tree{ |
| 352 | | .children = try children.toOwnedSlice(), |
| 353 | | }; |
| 354 | | } |
| 355 | | |
| 356 | 251 | fn parseTreeMode(input: string) !Tree.Object.Mode { |
| 357 | 252 | const t = tracer.trace(@src(), "", .{}); |
| 358 | 253 | defer t.end(); |