diff --git a/git.zig b/git.zig index 3af34f7224719f60ce1d569bfc8e945e9a37987f..ba168662533a983a84549e3ecc771cf40746c0a1 100644 --- a/git.zig +++ b/git.zig @@ -1,24 +1,29 @@ const std = @import("std"); const string = []const u8; +// 40 is length of sha1 hash +pub const Id = *const [40]u8; + /// Returns the result of running `git rev-parse HEAD` /// dir must already be pointing at the .git folder -pub fn getHEAD(alloc: std.mem.Allocator, dir: std.fs.Dir) !string { +pub fn getHEAD(alloc: std.mem.Allocator, dir: std.fs.Dir) !Id { const h = std.mem.trimRight(u8, try dir.readFileAlloc(alloc, "HEAD", 1024), "\n"); if (std.mem.startsWith(u8, h, "ref:")) { - return std.mem.trimRight(u8, try dir.readFileAlloc(alloc, h[5..], 1024), "\n"); + const r = std.mem.trimRight(u8, try dir.readFileAlloc(alloc, h[5..], 1024), "\n"); + std.debug.assert(r.len == 40); + return r[0..40]; } // content should be 40-char sha1 hash std.debug.assert(h.len == 40); - return h; + return h[0..40]; } // TODO make this inspect .git/objects // https://git-scm.com/book/en/v2/Git-Internals-Git-Objects // https://git-scm.com/book/en/v2/Git-Internals-Packfiles -pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: string) !string { +pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: Id) !string { const result = try std.ChildProcess.exec(.{ .allocator = alloc, .cwd_dir = dir, @@ -30,7 +35,7 @@ pub fn getObject(alloc: std.mem.Allocator, dir: std.fs.Dir, obj: string) !string pub fn parseCommit(alloc: std.mem.Allocator, commitfile: string) !Commit { var iter = std.mem.split(u8, commitfile, "\n"); var result: Commit = undefined; - var parents = std.ArrayList(string).init(alloc); + var parents = std.ArrayList(Id).init(alloc); errdefer parents.deinit(); while (true) { const line = iter.next().?; @@ -38,10 +43,10 @@ pub fn parseCommit(alloc: std.mem.Allocator, commitfile: string) !Commit { const space = std.mem.indexOfScalar(u8, line, ' ').?; const k = line[0..space]; - if (std.mem.eql(u8, k, "tree")) result.tree = line[space + 1 ..]; + if (std.mem.eql(u8, k, "tree")) result.tree = line[space + 1 ..][0..40]; if (std.mem.eql(u8, k, "author")) result.author = line[space + 1 ..]; if (std.mem.eql(u8, k, "committer")) result.committer = line[space + 1 ..]; - if (std.mem.eql(u8, k, "parent")) try parents.append(line[space + 1 ..]); + if (std.mem.eql(u8, k, "parent")) try parents.append(line[space + 1 ..][0..40]); } result.parents = try parents.toOwnedSlice(); result.message = iter.rest(); @@ -49,8 +54,8 @@ pub fn parseCommit(alloc: std.mem.Allocator, commitfile: string) !Commit { } pub const Commit = struct { - tree: string, - parents: []const string, + tree: Id, + parents: []const Id, author: string, committer: string, gpgsig: string,