╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │246 const head_oid = (try rf.readRecur(.xit, repo_opts, state.readOnly(), io, .{ .ref = ref })) orelse return error.OidNotFound;│ │247 try commit_iter.include(&head_oid); │ │248 │ │249 + // walk the commits and add all new events we haven't consumed yet. │ │250 + // the `next` call is using the arena because we need the parent_oids │ │251 + // slice to live beyond this scope. │ │252 + // TODO: `repo_events` could in theory contain an unbounded number │ │253 + // of events, so there is an OOM risk here. we definitely need to │ │254 + // guard against this. │ │255 while (try commit_iter.next(arena.allocator())) |commit_object| { │ │256 var oid: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │257 _ = try std.fmt.hexToBytes(&oid, &commit_object.oid); │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────╮ │258 │ │253 - // if this object id has already been consumed, skip it │ │259 + // if this object id has already been consumed, prune its ancestry from │ │260 + // the iterator. other queued paths, such as the second parent of a │ │261 + // merge commit, can still be walked until they hit a consumed commit │ │262 + // or run out of history. │ │263 if (null != try haxy_moments.getCursor(hash.bytesToInt(repo_opts.hash, &oid))) {│ │264 + try commit_iter.exclude(&commit_object.oid); │ │265 continue; │ │266 } │ │267 │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────╯