╭─────────────╮ │scroll to top│ ╰─────────────╯ ╭ Patch.zig ────────────────────────────────────────────────────╮ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ │ ╰───────────────────────────────────────────────────────────────╯
╭────╮ ╭ clone ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╮ │http│ ssh │ │ ╰────╯ ╰ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ─ ╯
368 const conflicts = try DB.SortedMap(.read_only).init(conflicts_cursor); 369 const conflict_cursor = (try conflicts.getCursor(&evt.orderKeyDesc(live.created_order, id))) orelse return updated; 370 const entry = try DB.HashMap(.read_only).init(conflict_cursor); 371 const fields_cursor = (try entry.getCursor(hash.hashInt(repo_opts.hash, evt.conflicted_fields_key))) orelse return updated; 372 const fields = try fields_cursor.readBytesAlloc(arena.allocator(), null); 373 const their_cursor = (try entry.getCursor(hash.hashInt(repo_opts.hash, evt.their_record_key))) orelse return updated; 374 const theirs = try evt.read(Record, DB, repo_opts.hash, arena, try DB.HashMap(.read_only).init(their_cursor)); 375 376 const original_target_branch = updated.target_branch; 377 var field_iter = std.mem.splitScalar(u8, fields, ' '); 378 while (field_iter.next()) |field| { 379 if (std.mem.eql(u8, field, "status") and fieldListed(resolve.theirs, ',', field)) updated.status = theirs.event.status; 380 if (std.mem.eql(u8, field, "revision") and fieldListed(resolve.theirs, ',', field)) updated.revision = theirs.event.revision; 381 if (std.mem.eql(u8, field, "target_branch") and fieldListed(resolve.theirs, ',', field)) updated.target_branch = theirs.event.target_branch; 382 } 383 if (!std.mem.eql(u8, original_target_branch, updated.target_branch)) updated.revision = null; 384 385 if (!fieldListed(fields, ' ', "description")) return updated; 386 var base_description: []const u8 = ""; 387 if (try entry.getCursor(hash.hashInt(repo_opts.hash, evt.base_record_key))) |base_cursor| { 388 const base = try evt.read(Record, DB, repo_opts.hash, arena, try DB.HashMap(.read_only).init(base_cursor)); 389 base_description = base.event.description; 390 } 391 const chunks = try diff3.chunks(allocator, arena, base_description, live.event.description, theirs.event.description); 392 var resolutions: std.ArrayList([]const u8) = .empty; 393 var hunk_index: usize = 0; 394 for (chunks) |chunk| { 395 if (chunk != .conflict) continue; 396 try resolutions.append(arena.allocator(), if (hunk_index < resolve.hunks.len) resolve.hunks[hunk_index] else (chunk.conflict.ours orelse "")); 397 hunk_index += 1; 398 } 399 updated.description = try diff3.assemble(arena.allocator(), chunks, resolutions.items); 400 return updated; 401 } 402 403 fn fieldListed(fields: []const u8, delimiter: u8, name: []const u8) bool { 404 var iter = std.mem.splitScalar(u8, fields, delimiter); 405 while (iter.next()) |field| { 406 if (std.mem.eql(u8, field, name)) return true; 407 } 408 return false; 409 } 410 411 fn revisionKey(allocator: std.mem.Allocator, target_branch: []const u8, oid: []const u8) ![]u8 { 412 return std.mem.concat(allocator, u8, &.{ target_branch, "\x00", oid }); 413 } 414 415 fn statusSet( 416 comptime DB: type, 417 statuses: DB.SortedMap(.read_write), 418 status: StatusKind, 419 ) !DB.SortedSet(.read_write) { 420 return DB.SortedSet(.read_write).init(try statuses.putCursor(@tagName(status))); 421 } 422 423 fn removeFromTagSets( 424 comptime DB: type, 425 tag_statuses: DB.SortedMap(.read_write), 426 tags: []const u8, 427 status: StatusKind, 428 order_key: []const u8, 429 ) !void { 430 var tag_iter = tagIterator(tags); 431 while (tag_iter.next()) |tag| { 432 if (tag.len == 0 or tag.len > tag_max_len) continue; 433 var key_buffer: TagStatusKey = undefined; 434 const key = try tagStatusKey(&key_buffer, tag, status); 435 const set = try DB.SortedSet(.read_write).init(try tag_statuses.putCursor(key)); 436 _ = try set.remove(order_key); 437 if (0 == try set.count()) _ = try tag_statuses.remove(key); 438 } 439 } 440 441 pub fn readById( 442 comptime DB: type, 443 comptime hash_kind: hash.HashKind, 444 haxy_moment: DB.HashMap(.read_only), 445 arena: *std.heap.ArenaAllocator, 446 id: *const [evt.event_id_size]u8, 447 ) !?Record { 448 const records_cursor = try haxy_moment.getCursor(hash.hashInt(hash_kind, record_map_key)) orelse return null; 449 const records = try DB.HashMap(.read_only).init(records_cursor); 450 const record_cursor = try records.getCursor(hash.hashInt(hash_kind, id)) orelse return null; 451 return try evt.read(Record, DB, hash_kind, arena, try DB.HashMap(.read_only).init(record_cursor)); 452 } 453