| ... | ... | @@ -1,24 +1,29 @@ |
| 1 | 1 | const std = @import("std"); |
| 2 | 2 | const string = []const u8; |
| 3 | 3 | |
| 4 | // 40 is length of sha1 hash |
| 5 | pub const Id = *const [40]u8; |
| 6 | |
| 4 | 7 | /// Returns the result of running `git rev-parse HEAD` |
| 5 | 8 | /// dir must already be pointing at the .git folder |
| 6 | | pub fn getHEAD(alloc: std.mem.Allocator, dir: std.fs.Dir) !string { |
| 9 | pub fn getHEAD(alloc: std.mem.Allocator, dir: std.fs.Dir) !Id { |
| 7 | 10 | const h = std.mem.trimRight(u8, try dir.readFileAlloc(alloc, "HEAD", 1024), "\n"); |
| 8 | 11 | |
| 9 | 12 | if (std.mem.startsWith(u8, h, "ref:")) { |
| 10 | | return std.mem.trimRight(u8, try dir.readFileAlloc(alloc, h[5..], 1024), "\n"); |
| 13 | const r = std.mem.trimRight(u8, try dir.readFileAlloc(alloc, h[5..], 1024), "\n"); |
| 14 | std.debug.assert(r.len == 40); |
| 15 | return r[0..40]; |
| 11 | 16 | } |
| 12 | 17 | |
| 13 | 18 | // content should be 40-char sha1 hash |
| 14 | 19 | std.debug.assert(h.len == 40); |
| 15 | | return h; |
| 20 | return h[0..40]; |
| 16 | 21 | } |
| 17 | 22 | |
| 18 | 23 | // TODO make this inspect .git/objects |
| 19 | 24 | // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects |
| 20 | 25 | // https://git-scm.com/book/en/v2/Git-Internals-Packfiles |
| 21 | | pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: string) !string { |
| 26 | pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !string { |
| 22 | 27 | const result = try std.ChildProcess.exec(.{ |
| 23 | 28 | .allocator = alloc, |
| 24 | 29 | .cwd_dir = dir, |
| ... | ... | @@ -30,7 +35,7 @@ pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: string) !string |
| 30 | 35 | pub fn parseCommit(alloc: std.mem.Allocator, commitfile: string) !Commit { |
| 31 | 36 | var iter = std.mem.split(u8, commitfile, "\n"); |
| 32 | 37 | var result: Commit = undefined; |
| 33 | | var parents = std.ArrayList(string).init(alloc); |
| 38 | var parents = std.ArrayList(Id).init(alloc); |
| 34 | 39 | errdefer parents.deinit(); |
| 35 | 40 | while (true) { |
| 36 | 41 | const line = iter.next().?; |
| ... | ... | @@ -38,10 +43,10 @@ pub fn parseCommit(alloc: std.mem.Allocator, commitfile: string) !Commit { |
| 38 | 43 | const space = std.mem.indexOfScalar(u8, line, ' ').?; |
| 39 | 44 | const k = line[0..space]; |
| 40 | 45 | |
| 41 | | if (std.mem.eql(u8, k, "tree")) result.tree = line[space + 1 ..]; |
| 46 | if (std.mem.eql(u8, k, "tree")) result.tree = line[space + 1 ..][0..40]; |
| 42 | 47 | if (std.mem.eql(u8, k, "author")) result.author = line[space + 1 ..]; |
| 43 | 48 | if (std.mem.eql(u8, k, "committer")) result.committer = line[space + 1 ..]; |
| 44 | | if (std.mem.eql(u8, k, "parent")) try parents.append(line[space + 1 ..]); |
| 49 | if (std.mem.eql(u8, k, "parent")) try parents.append(line[space + 1 ..][0..40]); |
| 45 | 50 | } |
| 46 | 51 | result.parents = try parents.toOwnedSlice(); |
| 47 | 52 | result.message = iter.rest(); |
| ... | ... | @@ -49,8 +54,8 @@ pub fn parseCommit(alloc: std.mem.Allocator, commitfile: string) !Commit { |
| 49 | 54 | } |
| 50 | 55 | |
| 51 | 56 | pub const Commit = struct { |
| 52 | | tree: string, |
| 53 | | parents: []const string, |
| 57 | tree: Id, |
| 58 | parents: []const Id, |
| 54 | 59 | author: string, |
| 55 | 60 | committer: string, |
| 56 | 61 | gpgsig: string, |