╭──────────╮ │← previous│ ╰──────────╯ ╭ changed ────╮ │src/patch.zig│ ╰─────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │421 │ │422 pub fn run(ctx: @This(), cursor: *DB.Cursor(.read_write)) !void { │ │423 const moment = try DB.HashMap(.read_write).init(cursor.*); │ │424 - const map = try DB.HashMap(.read_write).init(try moment.putCursor(hash.hashInt(repo_opts.hash, mergeability_key))); │ │424 + const last_object_id_cursor = try moment.getCursor(hash.hashInt(repo_opts.hash, evt.last_object_id_key)) orelse return error.NotFound; │ │425 + var last_object_id: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │426 + _ = try last_object_id_cursor.readBytes(&last_object_id); │ │427 + const haxy = try DB.ArrayList(.read_write).init(try moment.putCursor(hash.hashInt(repo_opts.hash, evt.materialized_key))); │ │428 + const haxy_moments = try DB.HashMap(.read_write).init(try haxy.putCursor(-1)); │ │429 + const haxy_moment = try DB.HashMap(.read_write).init(try haxy_moments.putCursor(hash.bytesToInt(repo_opts.hash, &last_object_id))); │ │430 + const map = try DB.HashMap(.read_write).init(try haxy_moment.putCursor(hash.hashInt(repo_opts.hash, evt.Patch.patch_id_to_mergeability_key)));│ │431 const entry = try DB.HashMap(.read_write).init(try map.putCursor(hash.hashInt(repo_opts.hash, &ctx.id))); │ │432 try evt.upsert(MergeCheck, DB, repo_opts.hash, entry, ctx.check); │ │433 + // discard the old repo-level cache as results are rebuilt here │ │434 + _ = try moment.remove(hash.hashInt(repo_opts.hash, evt.Patch.patch_id_to_mergeability_key)); │ │435 } │ │436 }; │ │437 const history = try DB.ArrayList(.read_write).init(target_repo.core.db.rootCursor()); │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───╮ │src/push.zig│ ╰────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │327 return err; │ │328 }; │ │329 │ │330 + find.refresh(repo_opts, io, allocator, fork_repo) catch |err| { │ │331 + serve_common.logError(io, error_writer, "failed to refresh file index: {s}\n", .{@errorName(err)});│ │332 + }; │ │333 + if (!published) return response.finish(writer, null); │ │334 + │ │335 var progress = PushProgress{ .response = &response, .writer = writer, .label = "Updating patches" }; │ │336 progress.run(io, .{ .start = .{ .kind = .writing_patch, .estimated_total_items = 1 } }) catch {}; │ │337 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │339 var refreshed = false; │ │340 update: { │ │341 const revision_id = revision_id_maybe orelse break :update; │ │337 - if (!published) break :update; │ │342 var update_arena = std.heap.ArenaAllocator.init(allocator); │ │343 defer update_arena.deinit(); │ │344 const target_update_moment = evt.currentMoment(repo_opts, target_repo) catch break :update;│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │367 } │ │368 │ │369 if (!refreshed) pch.refreshMergeability(repo_opts, io, allocator, target_repo, patch_id); │ │366 - find.refresh(repo_opts, io, allocator, fork_repo) catch |err| { │ │367 - serve_common.logError(io, error_writer, "failed to refresh file index: {s}\n", .{@errorName(err)});│ │368 - }; │ │370 progress.run(io, .{ .complete_one = .writing_patch }) catch {}; │ │371 progress.run(io, .{ .end = .writing_patch }) catch {}; │ │372 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────────────╮ │src/test/event/patch.zig│ ╰────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │970 } │ │971 try std.testing.expectError(error.NotFound, evt.currentMoment(repo_opts, &target)); │ │972 │ │973 + // draft mergeability checks leave the target repo untouched │ │974 + const before_draft_check = (try target.core.latestMoment()).cursor.slot(); │ │975 + pch.refreshMergeability(repo_opts, io, allocator, &target, patch_id); │ │976 + try std.testing.expectEqualDeep(before_draft_check, (try target.core.latestMoment()).cursor.slot());│ │977 + │ │978 // │ │979 // publish another draft before its first push │ │980 // │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1093 // merge the selected revision into the target │ │1094 // │ │1095 │ │1091 - try evt.Patch.update(.local, .xit, repo_opts, io, allocator, &target, &patch_id, .{ .status = .closed }, author); │ │1096 + try evt.Patch.update(.server, .xit, repo_opts, io, allocator, &target, &patch_id, .{ .status = .closed }, author);│ │1097 try std.testing.expectError(error.PatchClosed, pch.merge(repo_opts, io, allocator, repos_dir, &target, .{ │ │1098 .id = patch_id_hex, │ │1099 .revision = merge_revision, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1100 .author = author, │ │1101 .timestamp = 5, │ │1102 })); │ │1098 - try evt.Patch.update(.local, .xit, repo_opts, io, allocator, &target, &patch_id, .{ .status = .open }, author); │ │1103 + try evt.Patch.update(.server, .xit, repo_opts, io, allocator, &target, &patch_id, .{ .status = .open }, author);│ │1104 │ │1105 // run the cache scenario once; both lifecycle runs still perform a merge │ │1106 if (merge_revision == .source) { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │1177 } │ │1178 │ │1179 fn expectMergeabilityShortBytes(moment: Repo.DB.HashMap(.read_only), id: *const [evt.event_id_size]u8) !void { │ │1175 - const checks = try Repo.DB.HashMap(.read_only).init((try moment.getCursor(hash.hashInt(repo_opts.hash, "patch-id->mergeability"))) orelse return error.NotFound); │ │1180 + try std.testing.expectEqual(null, try moment.getCursor(hash.hashInt(repo_opts.hash, evt.Patch.patch_id_to_mergeability_key))); │ │1181 + const haxy_moment = try evt.currentMomentFromRepoMoment(repo_opts.hash, moment); │ │1182 + const checks = try Repo.DB.HashMap(.read_only).init((try haxy_moment.getCursor(hash.hashInt(repo_opts.hash, evt.Patch.patch_id_to_mergeability_key))) orelse return error.NotFound);│ │1183 const entry = try Repo.DB.HashMap(.read_only).init((try checks.getCursor(hash.hashInt(repo_opts.hash, id))) orelse return error.NotFound); │ │1184 const result = try Repo.DB.HashMap(.read_only).init((try entry.getCursor(hash.hashInt(repo_opts.hash, "result"))) orelse return error.NotFound); │ │1185 for ([_][]const u8{ "source", "squash" }) |field| { │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ───────╮ │src/test/net.zig│ ╰────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │617 defer admin.deinit(io, allocator); │ │618 var target = try rp.Repo(.xit, repo_opts).open(io, allocator, .{ .path = target_path }); │ │619 defer target.deinit(io, allocator); │ │620 + // pushing a draft does not create haxy state or a mergeability cache │ │621 + try std.testing.expectError(error.NotFound, evt.currentMoment(repo_opts, &target)); │ │622 + try std.testing.expectEqual(null, try (try target.core.latestMoment()).getCursor(hash.hashInt(hash_kind, evt.Patch.patch_id_to_mergeability_key)));│ │623 try target.addBranch(io, .{ .name = "feature" }); │ │624 try pch.publish(repo_opts, io, allocator, &admin, &target, draft_path, .{ │ │625 .id = fork_id_hex, │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯