╭ changed ────╮ │build.zig.zon│ ╰─────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────╮ │ 3 .version = "0.0.0", │ │ 4 .dependencies = .{ │ │ 5 .xit = .{ │ │ 6 - .url = "git+https://github.com/xit-vcs/xit#a03d42c2df8b99e7acd07a3f7f5649f4f030afea",│ │ 7 - .hash = "xit-0.0.0-Ub3nDC_AUAHpFNtNIafDErmwH_O1vlKiE0ybWJC6SQ4B", │ │ 6 + .url = "git+https://github.com/xit-vcs/xit#fa9e9c355634f65f5780b6f892ee401a901944c3",│ │ 7 + .hash = "xit-0.0.0-Ub3nDNvEUAGnWUtnr5lRInvueh0f0b3lYpsnVdYgdBC-", │ │ 8 }, │ │ 9 }, │ │10 .paths = .{ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────────────────────────────────────────╮ │ 5 const mrg = xit.merge; │ │ 6 const obj = xit.object; │ │ 7 const rf = xit.ref; │ │ 8 +const pch = @import("patch.zig"); │ │ 9 │ │10 pub const User = @import("event/User.zig");│ │11 pub const Repo = @import("event/Repo.zig");│ ╰───────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │23 // the branch haxy events are committed to before being consumed │ │24 pub const events_ref: rf.Ref = .{ .kind = .head, .name = "haxy/events" };│ │25 │ │26 +pub const materialized_key = "haxy"; │ │27 +pub const last_object_id_key = "haxy-last-object-id"; │ │28 + │ │29 // options + db type for the admin repo │ │30 pub const admin_repo_opts: rp.RepoOpts(.xit) = .{}; │ │31 pub const AdminDB = rp.Repo(.xit, admin_repo_opts).DB; │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────╮ │574 reader: *std.Io.Reader, │ │575 writer: *std.Io.Writer, │ │576 options: xit.net_server_receive_pack.Options,│ │577 + repo_root_path: []const u8, │ │578 ) !void { │ │579 const DB = rp.Repo(.xit, repo_opts).DB; │ │580 const State = rp.Repo(.xit, repo_opts).State;│ ╰──────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────╮ │586 reader: *std.Io.Reader, │ │587 writer: *std.Io.Writer, │ │588 options: xit.net_server_receive_pack.Options, │ │589 + repo_root_path: []const u8, │ │590 │ │591 pub fn run(ctx: @This(), cursor: *DB.Cursor(.read_write)) !void {│ │592 var moment = try DB.HashMap(.read_write).init(cursor.*); │ ╰──────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │593 const state = State(.read_write){ .core = ctx.core, .extra = .{ .moment = &moment } }; │ │588 - try xit.net_server_receive_pack.run(.xit, repo_opts, state, ctx.io, ctx.allocator, ctx.reader, ctx.writer, ctx.options); │ │589 - try xit.undo.writeMessage(repo_opts, state, .push); │ │594 + var updates = xit.net_server_receive_pack.AppliedRefUpdates.init(ctx.allocator); │ │595 + defer updates.deinit(); │ │596 + var receive_options = ctx.options; │ │597 + receive_options.applied_ref_updates = &updates; │ │598 + try xit.net_server_receive_pack.run(.xit, repo_opts, state, ctx.io, ctx.allocator, ctx.reader, ctx.writer, receive_options);│ │599 │ │600 // a repo without an events branch has no events to consume. a │ │601 // no-op consume must not cancel here, since the push shares the │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │602 // transaction and must commit regardless. │ │594 - if (null == try rf.readRecur(.xit, repo_opts, state.readOnly(), ctx.io, .{ .ref = events_ref })) return; │ │595 - _ = try consumeInTransaction(.repo, .xit, repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, events_ref); │ │603 + if (null != try rf.readRecur(.xit, repo_opts, state.readOnly(), ctx.io, .{ .ref = events_ref })) { │ │604 + _ = try consumeInTransaction(.repo, .xit, repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, events_ref); │ │605 + try pch.detectMerged(repo_opts, state, &ctx.core.db, &moment, ctx.io, ctx.allocator, ctx.repo_root_path, updates.items.items);│ │606 + } │ │607 + try xit.undo.writeMessage(repo_opts, state, .push); │ │608 + try ctx.core.chunk_store_file.sync(ctx.io); │ │609 } │ │610 }; │ │611 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │615 const history = try DB.ArrayList(.read_write).init(repo.core.db.rootCursor()); │ │616 history.appendContext( │ │617 .{ .slot = try history.getSlot(-1) }, │ │605 - Ctx{ .core = &repo.core, .io = io, .allocator = allocator, .reader = reader, .writer = writer, .options = options },│ │618 + Ctx{ │ │619 + .core = &repo.core, │ │620 + .io = io, │ │621 + .allocator = allocator, │ │622 + .reader = reader, │ │623 + .writer = writer, │ │624 + .options = options, │ │625 + .repo_root_path = repo_root_path, │ │626 + }, │ │627 ) catch |err| switch (err) { │ │628 error.CancelTransaction => {}, │ │629 else => |e| return e, │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │756 │ │757 // the last_object_id represents the object id that was last consumed │ │758 var last_object_id_maybe: ?[hash.byteLen(repo_opts.hash)]u8 = null; │ │738 - if (try moment.getCursor(hash.hashInt(repo_opts.hash, "haxy-last-object-id"))) |last_object_id_cursor| {│ │759 + if (try moment.getCursor(hash.hashInt(repo_opts.hash, last_object_id_key))) |last_object_id_cursor| { │ │760 var last_object_id_buffer: [hash.byteLen(repo_opts.hash)]u8 = undefined; │ │761 _ = try last_object_id_cursor.readBytes(&last_object_id_buffer); │ │762 last_object_id_maybe = last_object_id_buffer; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │774 // the reason it is a list is so we can keep every previous haxy │ │775 // state, making it easy to revert to an older state if the user │ │776 // rebases some of the past commits. │ │756 - const haxy_cursor = try moment.putCursor(hash.hashInt(repo_opts.hash, "haxy")); │ │777 + const haxy_cursor = try moment.putCursor(hash.hashInt(repo_opts.hash, materialized_key));│ │778 const haxy = try DB.ArrayList(.read_write).init(haxy_cursor); │ │779 │ │780 // add a new item to the haxy list created above. │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯