| ... | @@ -1206,7 +1206,8 @@ pub const Repository = struct { | ... | @@ -1206,7 +1206,8 @@ pub const Repository = struct { |
| 1206 | | 1206 | |
| 1207 | const base_idx = try r.getCommitA(arena, base_oid.id); | 1207 | const base_idx = try r.getCommitA(arena, base_oid.id); |
| 1208 | const base = base_idx.reify(r); | 1208 | const base = base_idx.reify(r); |
| 1209 | const base_tree = (try traverseTo(r, arena, base.tree, dir_path)).?; | 1209 | const base_tree_id = (try traverseTo(r, arena, base.tree, dir_path)).?; |
| | 1210 | const base_tree = try r.getTreeA(arena, base_tree_id.id); |
| 1210 | const total = base_tree.children.len(); | 1211 | const total = base_tree.children.len(); |
| 1211 | | 1212 | |
| 1212 | var found: usize = 0; | 1213 | var found: usize = 0; |
| ... | @@ -1222,13 +1223,14 @@ pub const Repository = struct { | ... | @@ -1222,13 +1223,14 @@ pub const Repository = struct { |
| 1222 | var commit_id = base_oid; | 1223 | var commit_id = base_oid; |
| 1223 | var commit_idx = base_idx; | 1224 | var commit_idx = base_idx; |
| 1224 | var commit = base; | 1225 | var commit = base; |
| | 1226 | var tree_id = base_tree_id; |
| 1225 | while (true) { | 1227 | while (true) { |
| 1226 | if (commit.parents.len == 0) break; | 1228 | if (commit.parents.len == 0) break; |
| 1227 | commit_id, commit_idx = (try r.getCommit(arena, commit.parents[0])).?; | 1229 | commit_id, commit_idx = (try r.getCommit(arena, commit.parents[0])).?; |
| 1228 | searched += 1; | 1230 | searched += 1; |
| 1229 | defer commit_id_prev = commit_id; | 1231 | defer commit_id_prev = commit_id; |
| 1230 | commit = commit_idx.reify(r); | 1232 | commit = commit_idx.reify(r); |
| 1231 | const tree = try traverseTo(r, arena, commit.tree, dir_path) orelse { | 1233 | const new_tree_id = try traverseTo(r, arena, commit.tree, dir_path) orelse { |
| 1232 | for (result.keys(), 0..) |k, i| { | 1234 | for (result.keys(), 0..) |k, i| { |
| 1233 | if (set.isSet(i)) continue; | 1235 | if (set.isSet(i)) continue; |
| 1234 | found += 1; | 1236 | found += 1; |
| ... | @@ -1239,6 +1241,9 @@ pub const Repository = struct { | ... | @@ -1239,6 +1241,9 @@ pub const Repository = struct { |
| 1239 | } | 1241 | } |
| 1240 | break; | 1242 | break; |
| 1241 | }; | 1243 | }; |
| | 1244 | if (new_tree_id.eql(tree_id)) continue; |
| | 1245 | tree_id = new_tree_id; |
| | 1246 | const tree = try r.getTreeA(arena, tree_id.id); |
| 1242 | for (result.keys(), 0..) |k, i| { | 1247 | for (result.keys(), 0..) |k, i| { |
| 1243 | if (set.isSet(i)) continue; | 1248 | if (set.isSet(i)) continue; |
| 1244 | const original = base_tree.get(k).?; | 1249 | const original = base_tree.get(k).?; |
| ... | @@ -1328,15 +1333,16 @@ const ZlibCode = enum(c_int) { | ... | @@ -1328,15 +1333,16 @@ const ZlibCode = enum(c_int) { |
| 1328 | Z_VERSION_ERROR = -6, | 1333 | Z_VERSION_ERROR = -6, |
| 1329 | }; | 1334 | }; |
| 1330 | | 1335 | |
| 1331 | fn traverseTo(r: *Repository, arena: std.mem.Allocator, treestart_id: TreeId, dir_path: []const u8) !?Tree { | 1336 | fn traverseTo(r: *Repository, arena: std.mem.Allocator, treestart_id: TreeId, dir_path: []const u8) !?TreeId { |
| 1332 | var tree = try r.getTreeA(arena, treestart_id.id); | 1337 | var id = treestart_id; |
| 1333 | if (dir_path.len == 0) return tree; | 1338 | if (dir_path.len == 0) return id; |
| 1334 | var iter = std.mem.splitScalar(u8, dir_path, '/'); | 1339 | var iter = std.mem.splitScalar(u8, dir_path, '/'); |
| 1335 | while (iter.next()) |segment| { | 1340 | while (iter.next()) |segment| { |
| | 1341 | const tree = try r.getTreeA(arena, id.id); |
| 1336 | const o = tree.get(segment) orelse return null; | 1342 | const o = tree.get(segment) orelse return null; |
| 1337 | tree = try r.getTreeA(arena, o.id.tree.id); | 1343 | id = o.id.tree; |
| 1338 | } | 1344 | } |
| 1339 | return tree; | 1345 | return id; |
| 1340 | } | 1346 | } |
| 1341 | | 1347 | |
| 1342 | pub const Tree = struct { | 1348 | pub const Tree = struct { |