╭ changed ────╮ │src/event.zig│ ╰─────────────╯ ╭───────────╮ │← all files│ ╰───────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │519 return try DB.HashMap(.read_only).init(haxy_moment_cursor); │ │520 } │ │521 │ │522 +// commit each event as a JSON commit message on `ref`, then consume them into │ │523 +// the db the repo's views read: the repo's own db, or the standalone local │ │524 +// event db when `is_local`. │ │525 pub fn commitAndConsume( │ │523 - comptime repo_opts: rp.RepoOpts(.xit), │ │526 + comptime repo_kind: rp.RepoKind, │ │527 + comptime repo_opts: rp.RepoOpts(repo_kind), │ │528 io: std.Io, │ │529 allocator: std.mem.Allocator, │ │526 - repo: *rp.Repo(.xit, repo_opts), │ │530 + repo: *rp.Repo(repo_kind, repo_opts), │ │531 ref: rf.Ref, │ │532 events: []const EventWithId, │ │533 + is_local: bool, │ │534 ) !void { │ │535 + // a branch that only exists on a remote continues from the remote tip, │ │536 + // so a cloned repo's local branch stays connected to the server history │ │537 + const first_parent_oids: ?[1][hash.hexLen(repo_opts.hash)]u8 = blk: { │ │538 + if (try repo.readRef(io, ref) != null) break :blk null; │ │539 + var remotes = try repo.listRemotes(io, allocator); │ │540 + defer remotes.deinit(); │ │541 + for (remotes.sections.keys()) |remote_name| { │ │542 + const remote_ref: rf.Ref = .{ .kind = .{ .remote = remote_name }, .name = ref.name }; │ │543 + if (try repo.readRef(io, remote_ref)) |oid| break :blk .{oid}; │ │544 + } │ │545 + break :blk null; │ │546 + }; │ │547 + var parent_oids: ?[]const [hash.hexLen(repo_opts.hash)]u8 = if (first_parent_oids) |*oids| oids else null;│ │548 + │ │549 var json: std.Io.Writer.Allocating = .init(allocator); │ │550 defer json.deinit(); │ │551 │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │552 for (events) |event| { │ │553 json.clearRetainingCapacity(); │ │554 try std.json.Stringify.value(event, .{}, &json.writer); │ │536 - _ = try repo.commitAtRef(io, allocator, .{ .message = json.written(), .timestamp = event.timestamp }, null, ref); │ │555 + _ = try repo.commitAtRef(io, allocator, .{ .author = "haxy <user@haxy>", .message = json.written(), .timestamp = event.timestamp, .parent_oids = parent_oids }, null, ref);│ │556 + // later events parent on the ref's new tip │ │557 + parent_oids = null; │ │558 } │ │559 │ │539 - try consume(repo_opts, io, allocator, repo, ref); │ │560 + if (is_local) { │ │561 + try syncLocalEvents(repo_kind, repo_opts, io, allocator, repo); │ │562 + } else switch (repo_kind) { │ │563 + .xit => try consume(repo_opts, io, allocator, repo, ref), │ │564 + // server repos are always xit │ │565 + .git => unreachable, │ │566 + } │ │567 } │ │568 │ │569 // build the key for SortedSets sorted by timestamp. the big-endian timestamp │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭───────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │574 std.mem.writeInt(u64, key[0..@sizeOf(u64)], timestamp, .big); │ │575 @memcpy(key[@sizeOf(u64)..], event_id); │ │576 return key; │ │577 +} │ │578 + │ │579 +pub fn orderKeyDesc(timestamp: u64, event_id: *const [event_id_size]u8) [@sizeOf(u64) + event_id_size]u8 {│ │580 + return orderKey(std.math.maxInt(u64) - timestamp, event_id); │ │581 } │ │582 │ │583 // split a pushed "<owner>/<repo>" path into its two components, or null if it │ ╰───────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │633 io.random(&id_bytes); │ │634 const event_id_hex = std.fmt.bytesToHex(id_bytes, .lower); │ │635 │ │605 - try commitAndConsume(admin_repo_opts, io, allocator, &repo, events_ref, &[_]EventWithId{.{ │ │636 + try commitAndConsume(.xit, admin_repo_opts, io, allocator, &repo, events_ref, &[_]EventWithId{.{│ │637 .id = event_id_hex, │ │638 .timestamp = @intCast(std.Io.Timestamp.now(io, .real).toSeconds()), │ │639 .event = .{ .repo = .{ │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────╮ │642 .description = "", │ │643 .enable_issue = true,│ │644 } }, │ │614 - }}); │ │645 + }}, false); │ │646 │ │647 return event_id_hex; │ │648 } │ ╰──────────────────────────────────────╯