Adjacent insertions conflict: an ordered 'keep both' could resolve them issue #121 closed: completed andymccall opened this · 3 comments
andymccall set labels feature ·
Design for review (no code yet).
What happens now. Two changes each add lines after the same line: in the file graph both insertions hang off the same anchor and neither orders the other, so materialize yields Segment::Conflict(sides) and the working copy gets markers. The sides come out in vertex order (by change hash), not by time. The same segment also comes from two changes that each replaced the same line (the old line dies, two insertions compete), so "keep both" is right only for the first case.
The two cases, told apart. A conflict is an adjacent insertion when no atom between its two live neighbours was deleted by a change on either side: the neighbours were next to each other before both changes. If either side deleted something there, it is an edit/edit conflict and keeping both would duplicate the edited lines.
Options
A. Resolve adjacent insertions automatically, in a fixed order (change time, or hash). Fewest conflicts, but it silently decides an order that can be wrong for code (two use lines are fine; two statements may not be), and it differs from Git.
B. (Recommended) Keep the conflict, make it one word to settle: oxy resolve --both PATH keeps every side of each adjacent-insertion conflict in PATH, earliest change first; --both --reverse the other way. It refuses an edit/edit conflict ("both sides changed these lines; edit the markers"). oxy status says which conflicts qualify: "2 conflicts are adjacent insertions: oxy resolve --both PATH keeps both". Markers list sides earliest change first too, so what you see is what --both keeps. The hub's proposal page could offer the same button.
C. (Follow-up, opt-in) A per-path merge rule, like Git's merge=union: files where order does not matter keep both sides automatically. The case that bites us daily is CHANGELOG.md: two proposals each add an Unreleased line and conflict. A rule such as CHANGELOG.md union in a repository file (.oxy/merge) would end those, without changing semantics anywhere else.
Recommendation: B now (small: the region check, the --both path in choose_resolutions, the status hint, marker order by time), then C for changelog-style files. A stays off.
Questions for Andy: B as described? Order: earliest change first (recommended), or the current hash order? And is C wanted soon (it would remove most of our own proposal conflicts)?
Decided (Andy, 2026-10-26): B now, then C. oxy resolve --both PATH keeps every side of each adjacent-insertion conflict, earliest change first (--reverse for the other order), refuses edit/edit conflicts, and oxy status says when it applies; markers list sides by time. Then an opt-in per-path rule in .oxy/merge (CHANGELOG.md union) so changelog lines stop conflicting. A stays off.
closed by change 9bd98cfb4f7e ·
Seen for real on oxygenhub proposal #333 (2026-10-26): two changelog entries added at the same place, but one side's change had also deleted the blank line between them, so --both rightly declined (a line between the neighbours was deleted by only one side) and the conflict came with a second, delete/insert one over that blank line. Resolved by hand. Worth considering: treat deleted blank lines between the neighbours as not counting, so a whitespace-only tidy on one side does not stop keep-both.
From Metal Gear (2026-10-18): two changes each adding a line after the same line conflicted. Git does the same, so it is defensible, but an ordered 'keep both' could resolve that case automatically. Needs a decision on the order (and whether it is automatic or a one-word resolution such as
oxy resolve --both): either order can be wrong for code, so silently choosing one is a semantics change.