unison/unison-src/transcripts/fix2004.md
2022-12-07 14:46:32 -05:00

2.3 KiB

.> builtins.merge

Here's the scenario that can produce bad empty namespace LCAs:

                              deletes of v4
j1: ... - v1 - v2 - v3 - v4 - v4a - v5 - v6 - v7
                                              /
                                  <empty> - v5a

                               adds of unrelated
j2: ... - v1 - v2 - v3 - v4 - x0 - x1 - x2 - x3
                                            /
                                <empty> - z1

So j1 and j2 have common history up through v4, then j1 deletes some definitions while j2 adds some definitions via shallow merges. These shallow merges then result in the LCA being the empty namespace rather than v4.

First, we create some common history before a fork:

.a> alias.term .builtin.Nat.+ delete1
.a> alias.term .builtin.Nat.* delete2
.a> alias.term .builtin.Nat.drop delete3
.a> alias.type .builtin.Nat Delete4

Now we fork a2 off of a. a continues on, deleting the terms it added previously and then adding one unrelated term via a merge with little history. It's this short history merge which will become a bad LCA of the empty namespace.

.> fork a a2
.a> delete.term.verbose delete1
.a> delete.term.verbose delete2
.a> delete.term.verbose delete3
.a> delete.type.verbose Delete4
.newbranchA> alias.term .builtin.Float.+ dontDelete
.> merge newbranchA a
.a> find

Meanwhile, a2 adds some other unrelated terms, some via merging in namespaces with little history. When merging a2 back into a, the deletes from their common history should be respected.

.a2> alias.term .builtin.Text.take keep1
.a2> alias.term .builtin.Text.take keep2
.a2> alias.term .builtin.Text.take keep3
.a2> alias.term .builtin.Text.take keep4
.a2> alias.term .builtin.Text.take keep5
.newbranchA2> alias.term .builtin.Text.take keep6
.> merge newbranchA2 a2
.a2> find
.> fork a asquash
.> merge a2 a
.> squash a2 asquash

At this point, all the things that a has deleted (delete1, delete2, etc) should be deleted in both the merged and squashed results. Let's verify this:

.a> find
.asquash> find
.> view a.keep1 a.keep2 a.keep3
.> view asquash.keep1 asquash.keep2 asquash.keep3
.> view a.Delete4
.> view asquash.delete1