5.5 KiB
Resolving edit conflicts in ucm
The ucm
tool tracks edits to hashes in an object called a patch. When patches get merged, sometimes those patches will have conflicting edits. The replace.term
command helps resolve such conflicts.
First, let's make a new namespace, example.resolve
:
.> cd example.resolve
☝️ The namespace .example.resolve is empty.
Now let's add a term named a.foo
:
a.foo = 42
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These new definitions are ok to `add`:
a.foo : Nat
.example.resolve> add
⍟ I've added these definitions:
a.foo : Nat
We'll fork the namespace a
into a new namespace b
, so we can edit the two concurrently.
.example.resolve> fork a b
Done.
We'll also make a second fork c
which we'll use as the target for our patch later.
.example.resolve> fork a c
Done.
Now let's make a change to foo
in the a
namespace:
.example.resolve> cd a
foo = 43
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These names already exist. You can `update` them to your
new definition:
foo : Nat
.example.resolve.a> update
⍟ I've updated these names to your new definition:
foo : Nat
And make a different change in the b
namespace:
.example.resolve> cd .example.resolve.b
foo = 44
I found and typechecked these definitions in scratch.u. If you
do an `add` or `update`, here's how your codebase would
change:
⍟ These names already exist. You can `update` them to your
new definition:
foo : Nat
.example.resolve.b> update
⍟ I've updated these names to your new definition:
foo : Nat
The a
and b
namespaces now each contain a patch named patch
. We can view these:
.example.resolve.b> cd .example.resolve
.example.resolve> view.patch a.patch
Edited Terms: c.foo -> a.foo
Tip: To remove entries from a patch, use
delete.term-replacement or delete.type-replacement, as
appropriate.
.example.resolve> view.patch b.patch
Edited Terms: c.foo -> b.foo
Tip: To remove entries from a patch, use
delete.term-replacement or delete.type-replacement, as
appropriate.
Let's now merge these namespaces into c
:
.example.resolve> merge a c
Here's what's changed in c after the merge:
Updates:
1. foo : Nat
↓
2. foo : Nat
Added definitions:
3. patch patch (added 1 updates)
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.
.example.resolve> merge b c
Here's what's changed in c after the merge:
New name conflicts:
1. foo#jdqoenu794 : Nat
↓
2. ┌ foo#8e68dvpr0a : Nat
3. └ foo#jdqoenu794 : Nat
Updates:
4. patch patch (added 1 updates)
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.
I tried to auto-apply the patch, but couldn't because it
contained contradictory entries.
The namespace c
now has an edit conflict, since the term foo
was edited in two different ways.
.example.resolve> cd c
.example.resolve.c> todo
❓
These definitions were edited differently in namespaces that
have been merged into this one. You'll have to tell me what to
use as the new definition:
The term foo#44954ulpdf was replaced with foo#8e68dvpr0a and
foo#jdqoenu794
We see that #44954ulpdf
(the original hash of a.foo
) got replaced with both the #8e68dvpr0a
and #jdqoenu794
.
We can resolve this conflict by picking one of the terms as the "winner":
.example.resolve.c> replace.term #44954ulpdf #8e68dvpr0a
Done.
This changes the merged c.patch
so that only the edit from #44954ulpdf to #8e68dvpr0a remains:
.example.resolve.c> view.patch
Edited Terms: foo#44954ulpdf -> foo#8e68dvpr0a
Tip: To remove entries from a patch, use
delete.term-replacement or delete.type-replacement, as
appropriate.
We still have a remaining name conflict since it just so happened that both of the definitions in the edits were named foo
.
.example.resolve.c> todo
❓
These terms have conflicting definitions: foo
Tip: This occurs when merging branches that both independently
introduce the same name. Use `view foo` to see the
conflicting defintions, then use `move.term` to resolve
the conflicts.
We can resolve the name conflict by deleting one of the names.
.example.resolve.c> delete.term foo#jdqoenu794
Resolved name conflicts:
1. ┌ example.resolve.c.foo#8e68dvpr0a : Nat
2. └ example.resolve.c.foo#jdqoenu794 : Nat
↓
3. example.resolve.c.foo#8e68dvpr0a : Nat
Name changes:
Original Changes
4. example.resolve.a.foo ┐ 5. example.resolve.c.foo#jdqoenu794 (removed)
6. example.resolve.c.foo#jdqoenu794 ┘
Tip: You can use `undo` or `reflog` to undo this change.
And that's how you resolve edit conflicts with UCM.