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