+const git = struct {
+ const Blob = struct {
+ data: []u8,
+ };
+ const TreeEntry = struct {
+ mode: []u8,
+ name: []u8,
+ hash: u160,
+ };
+ const Tree = std.ArrayList(TreeEntry);
+ const Commit = struct {
+ author: []u8,
+ message: []u8,
+ parent: u160,
+ Tree: u160,
+ };
+ const Object = struct {
+ usingnamespace union(enum) {
+ blob: Blob,
+ tree: Tree,
+ commit: Commit,
+ };
+ data: []const u8,
+ };
+ const Repo = struct {
+ pub fn init(alloc: std.mem.Allocator, path: []const u8) !@This() {
+ const gitDir = try std.fs.cwd().openDir(path, .{});
+
+ var objects = std.AutoHashMap(u160, Object).init(alloc);
+
+ var iter = gitDir.iterate();
+ while (try iter.next()) |dirEntry| {
+ if (std.mem.endsWith(u8, dirEntry.name, ".idx")) {
+ var packPathBuffer: [128]u8 = undefined;
+ const idxPath = try gitDir.realpathAlloc(alloc, dirEntry.name);
+ const packPath = try std.fmt.bufPrint(
+ &packPathBuffer,
+ "{s}.pack",
+ .{idxPath[0 .. idxPath.len - 4]},
+ );
+
+ const packBuffer = try std.fs.cwd().readFileAlloc(alloc, packPath, 1024 * 1024 * 1024 * 1024);
+ const idxBuffer = try std.fs.cwd().readFileAlloc(alloc, idxPath, 1024 * 1024 * 1024 * 1024);
+ defer alloc.free(packBuffer);
+ defer alloc.free(idxBuffer);
+
+ const pf = try PackFile.init(alloc, packBuffer, idxBuffer);
+ defer pf.deinit();
+
+ for (0..pf.objectNames.items.len) |i| {
+ try objects.put(
+ pf.objectNames.items[i],
+ try pf.getObject(alloc, pf.objectOffsets.items[i]),
+ );
+ }
+ }
+ }
+ return .{
+ .alloc = alloc,
+ .objects = objects,
+ };
+ }