]> gitweb.ps.run Git - ziggit/commitdiff
git.zig
authorPatrick Schönberger <patrick.schoenberger@posteo.de>
Mon, 20 May 2024 17:47:00 +0000 (19:47 +0200)
committerPatrick Schönberger <patrick.schoenberger@posteo.de>
Mon, 20 May 2024 17:47:00 +0000 (19:47 +0200)
git.zig [new file with mode: 0644]

diff --git a/git.zig b/git.zig
new file mode 100644 (file)
index 0000000..3baa985
--- /dev/null
+++ b/git.zig
@@ -0,0 +1,147 @@
+const std = @import("std");
+
+const Alloc = std.mem.Allocator;
+
+const Id = u160;
+const Commit = struct {
+    author: std.BoundedArray(u8, 64),
+    message: std.BoundedArray(u8, 1024),
+    parent: Id,
+    tree: Id,
+};
+const Blob = struct {
+    data: std.BoundedArray(u8, 1024),
+};
+const Object = struct {
+    alloc: Alloc,
+
+    // pub fn getCommit(self: *Object) Commit {}
+    // pub fn getBlob(self: *Object) Blob {}
+};
+const PackFile = struct {
+    alloc: Alloc,
+
+    pub fn init(alloc: Alloc) PackFile {
+        return .{
+            .alloc = alloc,
+        };
+    }
+    pub fn deinit(self: *PackFile) void {
+        _ = self;
+    }
+    pub fn parse(self: *PackFile, idxReader: std.io.AnyReader, pckReader: anytype) !void {
+        _ = self;
+        var buffer: [16]u8 = undefined;
+        _ = try idxReader.read(&buffer);
+        std.debug.print("{s}\n", .{&buffer});
+        _ = try pckReader.read(&buffer);
+        std.debug.print("{s}\n", .{&buffer});
+    }
+
+    // pub fn init(alloc: Alloc, path: []const u8) PackFile {}
+    // pub fn deinit(self: *PackFile) void {}
+    // pub fn getObject(self: *PackFile, id: Id) Object {}
+};
+const Repo = struct {
+    alloc: Alloc,
+    packfile: PackFile,
+
+    head: Id,
+
+    pub fn open(alloc: Alloc, path: []const u8) !Repo {
+        const dir = try std.fs.cwd().openDir(path, .{});
+
+        // read file HEAD
+        const head = try dir.readFileAlloc(alloc, "HEAD", 1024);
+        defer alloc.free(head);
+
+        // read file pointed at by HEAD
+        const headPath = head[5 .. head.len - 1];
+        var idBuffer: [40]u8 = undefined;
+        const idStr = try dir.readFile(headPath, &idBuffer);
+
+        // parse id from file
+        const id = try std.fmt.parseUnsigned(u160, idStr, 16);
+
+        // open any packfiles
+        var packfile = PackFile.init(alloc);
+        if (dir.openDir("objects/pack", .{ .iterate = true })) |packDir| {
+            var packIt = packDir.iterate();
+            while (try packIt.next()) |f| {
+                if (std.mem.endsWith(u8, f.name, ".idx")) {
+                    const idxFilename = f.name;
+                    var pckFilenameBuffer: [64]u8 = undefined;
+                    const pckFilename = try std.fmt.bufPrint(&pckFilenameBuffer, "{s}.pack", .{idxFilename[0 .. idxFilename.len - 4]});
+
+                    const idxFile = try packDir.openFile(idxFilename, .{});
+                    const pckFile = try packDir.openFile(pckFilename, .{});
+                    defer idxFile.close();
+                    defer pckFile.close();
+
+                    const idxReader = idxFile.reader().any();
+                    const pckReader = pckFile.reader().any();
+
+                    try packfile.parse(idxReader, pckReader);
+                }
+            }
+        } else |err| {
+            std.debug.print("{}\n", .{err});
+        }
+
+        return .{
+            .alloc = alloc,
+            .packfile = packfile,
+            .head = id,
+        };
+    }
+    pub fn close(self: *Repo) void {
+        self.packfile.deinit();
+    }
+    // pub fn getObject(self: *Repo, id: Id) Object {}
+};
+
+test "print HEAD" {
+    var repo = try Repo.open(std.testing.allocator, "../microwindows/.git");
+    defer repo.close();
+
+    std.debug.print("HEAD: {}\n", .{repo.head});
+}
+
+// test "list commits" {
+//     var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
+//     defer repo.close();
+
+//     const head = repo.getObject(repo.head);
+//     defer head.deinit();
+
+//     var c = head.getCommit();
+//     for (0..3) |_| {
+//         std.debug.print("{}\n", .{c});
+//         c = c.parent;
+//     }
+// }
+
+// test "tree" {
+//     var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
+//     defer repo.close();
+
+//     const head = repo.getObject(repo.head);
+//     defer head.deinit();
+
+//     const commit = head.getCommit();
+
+//     std.debug.print("{}\n", .{commit.tree});
+// }
+
+// test "blob" {
+//     var repo = Repo.open(std.testing.allocator, "../microwindows/.git");
+//     defer repo.close();
+
+//     const head = repo.getObject(repo.head);
+//     defer head.deinit();
+
+//     const commit = head.getCommit();
+//     const blob = repo.getBlob(commit.files[0].id);
+
+//     std.debug.print("{}\n", .{blob});
+// }