6.1 KiB
Here's the scenario that can produce bad empty namespace LCAs:
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:
☝️ The namespace .a is empty.
.a> alias.term .builtin.Nat.+ delete1
Done.
.a> alias.term .builtin.Nat.* delete2
Done.
.a> alias.term .builtin.Nat.drop delete3
Done.
.a> alias.type .builtin.Nat Delete4
Done.
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
Done.
.a> delete.term delete1
Name changes:
Original Changes
1. a.delete1 ┐ 2. a.delete1 (removed)
3. a2.delete1 │
4. builtin.Nat.+ ┘
Tip: You can use `undo` or `reflog` to undo this change.
.a> delete.term delete2
Name changes:
Original Changes
1. a.delete2 ┐ 2. a.delete2 (removed)
3. a2.delete2 │
4. builtin.Nat.* ┘
Tip: You can use `undo` or `reflog` to undo this change.
.a> delete.term delete3
Name changes:
Original Changes
1. a.delete3 ┐ 2. a.delete3 (removed)
3. a2.delete3 │
4. builtin.Nat.drop ┘
Tip: You can use `undo` or `reflog` to undo this change.
.a> delete.type Delete4
Name changes:
Original Changes
1. a.Delete4 ┐ 2. a.Delete4 (removed)
3. a2.Delete4 │
4. builtin.Nat ┘
Tip: You can use `undo` or `reflog` to undo this change.
☝️ The namespace .newbranchA is empty.
.newbranchA> alias.term .builtin.Float.+ dontDelete
Done.
.> merge newbranchA a
Here's what's changed in a after the merge:
Added definitions:
1. dontDelete : Float -> Float -> Float
Tip: You can use `todo` to see if this generated any work to
do in this namespace and `test` to run the tests. Or you
can use `undo` or `reflog` to undo the results of this
merge.
.a> find
1. dontDelete : Float -> Float -> Float
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
Done.
.a2> alias.term .builtin.Text.take keep2
Done.
.a2> alias.term .builtin.Text.take keep3
Done.
.a2> alias.term .builtin.Text.take keep4
Done.
.a2> alias.term .builtin.Text.take keep5
Done.
☝️ The namespace .newbranchA2 is empty.
.newbranchA2> alias.term .builtin.Text.take keep6
Done.
.> merge newbranchA2 a2
Here's what's changed in a2 after the merge:
Name changes:
Original Changes
1. keep1 ┐ 2. keep6 (added)
3. keep2 │
4. keep3 │
5. keep4 │
6. keep5 ┘
Tip: You can use `todo` to see if this generated any work to
do in this namespace and `test` to run the tests. Or you
can use `undo` or `reflog` to undo the results of this
merge.
.a2> find
1. delete1 : Delete4 -> Delete4 -> Delete4
2. delete2 : Delete4 -> Delete4 -> Delete4
3. delete3 : Delete4 -> Delete4 -> Delete4
4. builtin type Delete4
5. keep1 : Delete4 -> Text -> Text
6. keep2 : Delete4 -> Text -> Text
7. keep3 : Delete4 -> Text -> Text
8. keep4 : Delete4 -> Text -> Text
9. keep5 : Delete4 -> Text -> Text
10. keep6 : Delete4 -> Text -> Text
.> fork a asquash
Done.
.> merge a2 a
Here's what's changed in a after the merge:
Added definitions:
1. ┌ keep1 : Delete4 -> Text -> Text
2. │ keep2 : Delete4 -> Text -> Text
3. │ keep3 : Delete4 -> Text -> Text
4. │ keep4 : Delete4 -> Text -> Text
5. │ keep5 : Delete4 -> Text -> Text
6. └ keep6 : Delete4 -> Text -> Text
Tip: You can use `todo` to see if this generated any work to
do in this namespace and `test` to run the tests. Or you
can use `undo` or `reflog` to undo the results of this
merge.
.> squash a2 asquash
Here's what's changed in asquash after the merge:
Added definitions:
1. ┌ keep1 : Delete4 -> Text -> Text
2. │ keep2 : Delete4 -> Text -> Text
3. │ keep3 : Delete4 -> Text -> Text
4. │ keep4 : Delete4 -> Text -> Text
5. │ keep5 : Delete4 -> Text -> Text
6. └ keep6 : Delete4 -> Text -> Text
Tip: You can use `todo` to see if this generated any work to
do in this namespace and `test` to run the tests. Or you
can use `undo` or `reflog` to undo the results of this
merge.
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
1. dontDelete : Float -> Float -> Float
2. keep1 : Delete4 -> Text -> Text
3. keep2 : Delete4 -> Text -> Text
4. keep3 : Delete4 -> Text -> Text
5. keep4 : Delete4 -> Text -> Text
6. keep5 : Delete4 -> Text -> Text
7. keep6 : Delete4 -> Text -> Text
.asquash> find
1. dontDelete : Float -> Float -> Float
2. keep1 : Delete4 -> Text -> Text
3. keep2 : Delete4 -> Text -> Text
4. keep3 : Delete4 -> Text -> Text
5. keep4 : Delete4 -> Text -> Text
6. keep5 : Delete4 -> Text -> Text
7. keep6 : Delete4 -> Text -> Text
.> view a.Delete4
⚠️
The following names were not found in the codebase. Check your spelling.
a.Delete4
.> view asquash.delete1
⚠️
The following names were not found in the codebase. Check your spelling.
asquash.delete1