treesummaryrefslogcommitdiff
path: root/git.zig
blob: fe828705d0dde459fcae8a930ddb47e18ef81783 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
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 open(alloc: Alloc, dir: std.fs.Dir) !PackFile {
        var self = PackFile{ .alloc = alloc };

        var packDir = try dir.openDir("objects/pack", .{ .iterate = true });
        defer packDir.close();

        var packIt = packDir.iterate();
        while (try packIt.next()) |f| {
            if (std.mem.endsWith(u8, f.name, ".idx")) {
                const idxFilename = f.name;
                var pckFilename = try std.BoundedArray(u8, std.fs.max_path_bytes).init(0);
                try std.fmt.format(
                    pckFilename.writer(),
                    "{s}.pack",
                    .{idxFilename[0 .. idxFilename.len - 4]},
                );

                const idxFile = try packDir.openFile(idxFilename, .{});
                const pckFile = try packDir.openFile(pckFilename.constSlice(), .{});
                defer idxFile.close();
                defer pckFile.close();

                const idxReader = idxFile.reader().any();
                const pckReader = pckFile.reader().any();

                try self.parse(idxReader, pckReader);
            }
        }

        return self;
    }
    pub fn parse(self: *PackFile, idxReader: std.io.AnyReader, pckReader: std.io.AnyReader) !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,
    dir: std.fs.Dir,
    packfile: PackFile,

    pub fn open(alloc: Alloc, path: []const u8) !Repo {
        const dir = try std.fs.cwd().openDir(path, .{});

        const packfile = try PackFile.open(alloc, dir);

        return .{
            .alloc = alloc,
            .dir = dir,
            .packfile = packfile,
        };
    }
    pub fn close(self: *Repo) void {
        self.dir.close();
    }
    pub fn getHead(self: *Repo) !Id {
        // read file HEAD
        const head = try self.dir.readFileAlloc(self.alloc, "HEAD", 1024);
        defer self.alloc.free(head);

        // read file pointed at by HEAD
        const headPath = head[5 .. head.len - 1];
        var idBuffer: [40]u8 = undefined;
        const idStr = try self.dir.readFile(headPath, &idBuffer);

        // parse id from file
        return try std.fmt.parseUnsigned(u160, idStr, 16);
    }
    // pub fn getObject(self: *Repo, id: Id) Object {}
};

test "print HEAD" {
    var repo = try Repo.open(std.testing.allocator, "../microwindows/.git");
    defer repo.close();

    const head = try repo.getHead();

    std.debug.print("HEAD: {}\n", .{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});
// }