╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │121 if (repo_event.parent_oid) |*parent_oid| { │ │122 if (!std.mem.eql(u8, last_object_id, parent_oid)) { │ │123 // the last-object-id does not match the current event's parent id. │ │124 - // this means that a rebase occurred. what we need to do is just │ │125 - // revert the two object-id maps to the state they were in when │ │126 - // parent-oid was consumed. │ │124 + // this means that a rebase occurred. we just need to revert the │ │125 + // object-id maps to the state they were in when parent-oid was consumed. │ │126 │ │127 const object_id_to_tx_id = try DB.HashMap(.read_only).init(object_id_to_tx_id_cursor.readOnly()); │ │128 const tx_id_cursor = try object_id_to_tx_id.getCursor(hash.bytesToInt(hash_kind, parent_oid)) orelse return error.ObjectNotFound;│ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────╮ │147 // the branch was rebased all the way to the very beginning. │ │148 // we have a repo event with no parent, which means it is now│ │149 // the very first event. all we need to do is set the │ │151 - // object-id->views map to be empty so we can rebuild it. │ │150 + // object-id maps to be empty. │ │151 + try object_id_to_tx_id_cursor.write(.{ .slot = null }); │ │152 try object_id_to_views_cursor.write(.{ .slot = null }); │ │153 } │ │154 } else { │ ╰──────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ─────────╮ │src/test/event.zig│ ╰──────────────────╯ ╭─────────────────────────────────────────────────────────────────────╮ │218 } │ │219 │ │220 // │ │221 - // define new test events without the edit event │ │222 - // and insert them into the repo │ │221 + // rebase the branch so it no longer includes the edit event│ │222 // │ │223 │ │224 const rebased_events_to_consume = [_]evt.Event{ │ ╰─────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │317 │ │318 // the tags are no longer edited │ │319 try std.testing.expectEqualStrings(events_to_consume[0].data.issue.tags, first_issue.issue.tags); │ │320 + } │ │321 + │ │322 + // │ │323 + // rebase the branch so it no longer includes the original issue │ │324 + // │ │325 + │ │326 + { │ │327 + var json: std.Io.Writer.Allocating = .init(std.testing.allocator); │ │328 + defer json.deinit(); │ │329 + │ │330 + for (rebased_events_to_consume, 0..) |event, i| { │ │331 + json.clearRetainingCapacity(); │ │332 + │ │333 + try std.json.Stringify.value(event, .{}, &json.writer); │ │334 + │ │335 + // commit the event into a special branch │ │336 + _ = try repo.commitAtRef( │ │337 + io, │ │338 + allocator, │ │339 + .{ │ │340 + .message = json.written(), │ │341 + // the first event should have no parents, │ │342 + // because we want to drop the very first commit. │ │343 + // and the rest will have null which causes them │ │344 + // to have the previous commit as their parent │ │345 + .parent_oids = if (i == 0) &.{} else null, │ │346 + }, │ │347 + null, │ │348 + .{ .kind = .head, .name = "haxy/meta" }, │ │349 + ); │ │350 + } │ │351 + } │ │352 + │ │353 + // │ │354 + // read and parse all of the events from the repo │ │355 + // │ │356 + │ │357 + events.clearRetainingCapacity(); │ │358 + │ │359 + { │ │360 + const commits = try Commit.readCommitsFromRepo(&arena, &repo, "haxy/meta"); │ │361 + │ │362 + // parse commit messages as JSON into event values. │ │363 + // add events in reverse order so the earliest event is first. │ │364 + for (0..commits.len) |i| { │ │365 + const commit = commits[commits.len - i - 1]; │ │366 + const event = try std.json.parseFromSliceLeaky(evt.Event, arena.allocator(), commit.message, .{}); │ │367 + try events.append(allocator, .{ │ │368 + .parent_oid = commit.parent_oid, │ │369 + .oid = commit.oid, │ │370 + .event = event, │ │371 + }); │ │372 + } │ │373 + } │ │374 + │ │375 + // │ │376 + // consume events into the database │ │377 + // │ │378 + │ │379 + { │ │380 + try evt.consume(Repo.DB, repo_opts.hash, io, &repo.core.db, repo.core.db_file, events.items); │ │381 + │ │382 + const history = try Repo.DB.ArrayList(.read_only).init(repo.core.db.rootCursor().readOnly()); │ │383 + │ │384 + // read the moment we just created │ │385 + const moment_cursor = try history.getCursor(-1) orelse return error.NotFound; │ │386 + const moment = try Repo.DB.HashMap(.read_only).init(moment_cursor); │ │387 + │ │388 + const haxy_cursor = try moment.getCursor(hash.hashInt(repo_opts.hash, "haxy")) orelse return error.NotFound; │ │389 + const haxy = try Repo.DB.HashMap(.read_only).init(haxy_cursor); │ │390 + │ │391 + const object_id_to_views_cursor = try haxy.getCursor(hash.hashInt(repo_opts.hash, "object-id->views")) orelse return error.NotFound; │ │392 + const object_id_to_views = try Repo.DB.HashMap(.read_only).init(object_id_to_views_cursor); │ │393 + │ │394 + // get the last object id │ │395 + const last_object_id_cursor = try haxy.getCursor(hash.hashInt(repo_opts.hash, "last-object-id")) orelse return error.NotFound; │ │396 + var last_object_id: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │397 + _ = try last_object_id_cursor.readBytes(&last_object_id); │ │398 + │ │399 + // get the latest views (the views generated by the last object id) │ │400 + const views_cursor = try object_id_to_views.getCursor(hash.bytesToInt(repo_opts.hash, &last_object_id)) orelse return error.NotFound;│ │401 + const views = try Repo.DB.HashMap(.read_only).init(views_cursor); │ │402 + │ │403 + // get the map of issues │ │404 + const event_id_to_issue_cursor = try views.getCursor(hash.hashInt(repo_opts.hash, "event-id->issue")) orelse return error.NotFound; │ │405 + const event_id_to_issue = try Repo.DB.HashMap(.read_only).init(event_id_to_issue_cursor); │ │406 + │ │407 + // the first issue no longer exists │ │408 + try std.testing.expect(null == try event_id_to_issue.getCursor(hash.hashInt(repo_opts.hash, &first_event_id))); │ │409 } │ │410 } │ │411 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯