diff --git a/git.zig b/git.zig index d7ca6836029da2cb24e694cd8426a402cf5f03a0..23ecd002fb0553e03981d2454d46c66f087a1b60 100644 --- a/git.zig +++ b/git.zig @@ -1654,13 +1654,14 @@ pub const Repository = struct { const base = try r.getCommitA(from.id, .no_cache); const base_tree = try r.getTreeA(base.tree.id, .no_cache); - const base_id, const base_id_parent = (try idFor(r, base_tree, sub_path)).?; + const base_obj, const base_id_parent = (try idFor(r, base_tree, sub_path)).?; var prev_prev_commit: ?*Commit = null; var prev_commit = base; var prev_tree = base_id_parent; - var prev_id = try r.gpa.dupe(u8, base_id); - defer r.gpa.free(prev_id); + var prev_obj = try r.gpa.create(Tree.Object); + prev_obj.* = base_obj.*; + defer r.gpa.destroy(prev_obj); while (true) { if (prev_commit.parents.len == 0) { @@ -1669,11 +1670,11 @@ pub const Repository = struct { } const next_commit = try r.getCommitA(prev_commit.parents[0].id, .no_cache); const next_commit_tree = try r.getTreeA(next_commit.tree.id, .no_cache); - const next_id, const next_tree = try idFor(r, next_commit_tree, sub_path) orelse { + const next_obj, const next_tree = try idFor(r, next_commit_tree, sub_path) orelse { try list.appendSlice(alloc, prev_prev_commit.?.parents[0].id ++ "\n"); break; }; - if (std.mem.eql(u8, next_id, prev_id)) { + if (std.mem.eql(u8, &next_obj.id_bytes, &prev_obj.id_bytes) and next_obj.mode.eql(prev_obj.mode)) { if (prev_prev_commit) |p| p.destroy(r); prev_prev_commit = prev_commit; prev_commit = next_commit; @@ -1685,9 +1686,7 @@ pub const Repository = struct { prev_prev_commit = prev_commit; prev_commit = next_commit; prev_tree = next_tree; - - r.gpa.free(prev_id); - prev_id = try r.gpa.dupe(u8, next_id); + prev_obj.* = next_obj.*; continue; } @@ -1786,7 +1785,7 @@ pub const Tree = struct { r.gpa.destroy(t); } - pub fn get(self: *Tree, name: string) ?Object { + pub fn get(self: *Tree, name: string) ?*const Object { // modified std.sort.binarySearch const i = blk: { var low: usize = 0; @@ -1813,10 +1812,10 @@ pub const Tree = struct { } return null; }; - return self.children[i]; + return &self.children[i]; } - pub fn getBlob(self: *Tree, name: string, hint: Object.Type) ?Object { + pub fn getBlob(self: *Tree, name: string, hint: Object.Type) ?*const Object { const o = self.get(name, hint) orelse return null; if (o.id != .blob) return null; return o; @@ -2150,7 +2149,7 @@ const PathListNode = struct { }; /// Consumes 'tree' and returns a new owned 'Tree' in the tuple. -pub fn idFor(r: *Repository, tree: *Tree, sub_path: []const u8) !?struct { Id, *Tree } { +pub fn idFor(r: *Repository, tree: *Tree, sub_path: []const u8) !?struct { *const Tree.Object, *Tree } { const s_idx = std.mem.indexOfScalar(u8, sub_path, '/'); const seg = sub_path[0 .. s_idx orelse sub_path.len]; const obj = tree.get(seg) orelse { @@ -2164,12 +2163,12 @@ pub fn idFor(r: *Repository, tree: *Tree, sub_path: []const u8) !?struct { Id, * const new_tree = try r.getTreeA(id.id, .no_cache); return idFor(r, new_tree, sub_path[s_idx.? + 1 ..]); }, - else => |id| { + else => { if (s_idx != null) { tree.destroy(r); return null; } - return .{ id.erase(), tree }; + return .{ obj, tree }; }, } }