╭ changed ──────────╮ │src/event/Patch.zig│ ╰───────────────────╯ ╭───────────────────────────────────────────────────────╮ │ 9 title: []const u8, │ │10 description: []const u8, │ │11 tags: []const u8, // space-separated │ │12 +target_branch: []const u8, │ │13 target_patch_id: ?[evt.event_id_size * 2]u8 = null,│ │14 revision: ?Revision = null, │ │15 status: Status = .open, │ ╰───────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────╮ │18 id: [evt.event_id_size * 2]u8, │ │19 squash_oid: []const u8, │ │20 source_oid: []const u8, │ │20 - target_ref: []const u8, │ │21 │ │22 pub fn fromRecord(id: [evt.event_id_size]u8, record: evt.PatchRev.Record) Revision {│ │23 return .{ │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────╮ │24 .id = std.fmt.bytesToHex(id, .lower), │ │25 .squash_oid = record.patch_oid, │ │26 .source_oid = record.event.source_oid,│ │27 - .target_ref = record.event.target_ref,│ │27 }; │ │28 } │ │29 │ ╰──────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────╮ │30 pub fn matches(self: Revision, record: evt.PatchRev.Record) bool { │ │31 return !record.removed and │ │32 std.mem.eql(u8, record.patch_oid, self.squash_oid) and │ │34 - std.mem.eql(u8, record.event.source_oid, self.source_oid) and│ │35 - std.mem.eql(u8, record.event.target_ref, self.target_ref); │ │33 + std.mem.eql(u8, record.event.source_oid, self.source_oid); │ │34 } │ │35 │ │36 pub fn includesOid(self: Revision, oid: []const u8) bool { │ ╰─────────────────────────────────────────────────────────────────────────────╯ ╭──────────────────────────────────────────────────────────────────────────────────────────────────╮ │37 return std.mem.eql(u8, oid, self.source_oid) or std.mem.eql(u8, oid, self.squash_oid);│ │40 - } │ │41 - │ │42 - pub fn targetBranch(self: Revision) ?[]const u8 { │ │43 - const target_ref = rf.Ref.initFromPath(self.target_ref, null) orelse return null; │ │44 - return switch (target_ref.kind) { │ │45 - .head => target_ref.name, │ │46 - else => null, │ │47 - }; │ │38 } │ │39 }; │ │40 │ ╰──────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │118 │ │119 pub const Update = union(enum) { │ │120 status: StatusKind, │ │131 - fields: struct { title: []const u8, tags: []const u8, description: []const u8 }, │ │121 + fields: struct { title: []const u8, tags: []const u8, description: []const u8, target_branch: []const u8 },│ │122 resolve: Resolve, │ │123 }; │ │124 │ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────╮ │131 pub const target_patch_id_to_patch_id_set_key = "target-patch-id->patch-id-set";│ │132 pub const status_to_id_set_key = "status->patch-id-set"; │ │133 pub const tag_status_to_id_set_key = "tag+status->patch-id-set"; │ │144 -pub const revision_to_id_set_key = "target-ref+oid->patch-id-set"; │ │134 +pub const revision_to_id_set_key = "target-branch+oid->patch-id-set"; │ │135 │ │136 pub const TagStatusKey = [tag_max_len + 1 + StatusKind.longest_len]u8; │ │137 │ ╰─────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────╮ │183 }; │ │184 │ │185 if (!fieldsValid(record.event.title, record.event.tags)) return error.InvalidPatch;│ │186 + if (!rf.validateName(record.event.target_branch)) return error.InvalidTarget; │ │187 const revision_id = if (record.event.revision) |*revision| blk: { │ │188 try evt.PatchRev.validateOid(hash_kind, revision.squash_oid); │ │189 try evt.PatchRev.validateOid(hash_kind, revision.source_oid); │ ╰────────────────────────────────────────────────────────────────────────────────────────────╯ ╭────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │199 - try evt.PatchRev.validateTarget(revision.target_ref); │ │190 break :blk try evt.parseEventId(&revision.id); │ │191 } else null; │ │192 const target_patch_id = if (record.event.target_patch_id) |*id| try evt.parseEventId(id) else null;│ ╰────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╮ │200 record.author_email = existing.author_email; │ │201 const existing_status_kind = existing.event.status.kind(); │ │202 if (existing_status_kind == .merged and !evt.fieldEqual(Status, existing.event.status, record.event.status)) return error.PatchAlreadyMerged; │ │203 + if (existing_status_kind == .merged and !std.mem.eql(u8, existing.event.target_branch, record.event.target_branch)) return error.PatchAlreadyMerged;│ │204 if (event_oid != null) { │ │205 if (!std.meta.eql(existing.event.target_patch_id, record.event.target_patch_id)) { │ │206 return error.TargetPatchChanged; │ ╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯ ╭──────╮ │next →│ ╰──────╯