unison/unison-src/transcripts/merge.output.md

2428 lines
44 KiB
Markdown
Raw Permalink Normal View History

2024-04-24 18:49:03 +03:00
# The `merge` command
2020-02-20 17:17:10 +03:00
2024-04-24 18:49:03 +03:00
The `merge` command merges together two branches in the same project: the current branch (unspecificed), and the target
2024-06-11 21:15:30 +03:00
branch. For example, to merge `topic` into `main`, switch to `main` and run `merge topic`:
2020-02-20 17:17:10 +03:00
``` ucm
2024-07-01 20:28:52 +03:00
scratch/main> help merge
2024-06-11 21:15:30 +03:00
2024-07-05 19:54:35 +03:00
merge
`merge /branch` merges `branch` into the current branch
2024-06-11 21:15:30 +03:00
2024-07-01 20:28:52 +03:00
scratch/main> help merge.commit
2024-06-11 21:15:30 +03:00
2024-07-05 19:54:35 +03:00
merge.commit (or commit.merge)
`merge.commit` merges a temporary branch created by the
`merge` command back into its parent branch, and removes the
temporary branch.
2024-07-05 19:54:35 +03:00
For example, if you've done `merge topic` from main, then
2024-07-05 19:54:35 +03:00
`merge.commit` is equivalent to doing
2024-07-05 19:54:35 +03:00
* switch /main
* merge /merge-topic-into-main
* delete.branch /merge-topic-into-main
2024-06-11 21:15:30 +03:00
```
2024-04-24 18:49:03 +03:00
Let's see a simple unconflicted merge in action: Alice (us) and Bob (them) add different terms. The merged result
contains both additions.
2020-02-20 17:17:10 +03:00
2024-04-24 18:49:03 +03:00
## Basic merge: two unconflicted adds
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
Alice's adds:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alices foo"
```
2024-05-07 20:04:16 +03:00
Bob's adds:
``` unison
2024-04-24 18:49:03 +03:00
bar : Text
bar = "bobs bar"
2020-02-20 17:17:10 +03:00
```
2024-05-07 20:04:16 +03:00
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2020-02-20 17:17:10 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2020-02-20 17:17:10 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo bar
2024-04-24 18:49:03 +03:00
bar : Text
bar = "bobs bar"
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alices foo"
```
2024-05-07 20:04:16 +03:00
## Basic merge: two identical adds
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
If Alice and Bob also happen to add the same definition, that's not a conflict.
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
Alice's adds:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alice and bobs foo"
2020-02-20 17:17:10 +03:00
```
2024-05-07 20:04:16 +03:00
Bob's adds:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alice and bobs foo"
bar : Text
bar = "bobs bar"
2020-02-20 17:17:10 +03:00
```
2024-05-07 20:04:16 +03:00
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2020-02-20 17:17:10 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2020-02-20 17:17:10 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo bar
2020-02-20 17:17:10 +03:00
2024-04-24 18:49:03 +03:00
bar : Text
bar = "bobs bar"
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alice and bobs foo"
2020-02-20 17:17:10 +03:00
```
2024-04-24 18:49:03 +03:00
## Simple update propagation
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
Updates that occur in one branch are propagated to the other. In this example, Alice updates `foo`, while Bob adds a new dependent `bar` of the original `foo`. When Bob's branch is merged into Alice's, her update to `foo` is propagated to his `bar`.
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "old foo"
```
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
Alice's updates:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "new foo"
```
2023-05-17 20:36:58 +03:00
2024-05-07 20:04:16 +03:00
Bob's adds:
``` unison
2024-04-24 18:49:03 +03:00
bar : Text
2024-05-07 20:04:16 +03:00
bar = foo ++ " - " ++ foo
2024-04-24 18:49:03 +03:00
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> display bar
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
"old foo - old foo"
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2023-05-17 20:36:58 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2020-02-20 17:17:10 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo bar
2024-04-24 18:49:03 +03:00
bar : Text
bar =
use Text ++
2024-05-07 20:04:16 +03:00
foo ++ " - " ++ foo
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
foo = "new foo"
2024-09-05 17:44:48 +03:00
scratch/alice> display bar
2024-05-07 20:04:16 +03:00
"old foo - old foo"
2024-04-24 18:49:03 +03:00
```
## Update propagation with common dependent
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
We classify something as an update if its "syntactic hash"—not its normal Unison hash—differs from the original definition. This allows us to cleanly merge unconflicted updates that were individually propagated to a common dependent.
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
Let's see an example. We have `foo`, which depends on `bar` and `baz`. Alice updates `bar` (propagating to `foo`), and Bob updates `baz` (propagating to `foo`). When we merge their updates, both updates will be reflected in the final `foo`.
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
2024-05-07 20:04:16 +03:00
foo = "foo" ++ " - " ++ bar ++ " - " ++ baz
2024-04-24 18:49:03 +03:00
bar : Text
bar = "old bar"
baz : Text
baz = "old baz"
```
2024-05-07 20:04:16 +03:00
Alice's updates:
``` unison
2024-04-24 18:49:03 +03:00
bar : Text
bar = "alices bar"
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> display foo
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
"foo - alices bar - old baz"
2020-02-20 17:17:10 +03:00
```
2024-05-07 20:04:16 +03:00
Bob's updates:
``` unison
2024-04-24 18:49:03 +03:00
baz : Text
baz = "bobs baz"
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> display foo
2020-02-20 17:17:10 +03:00
2024-05-07 20:04:16 +03:00
"foo - old bar - bobs baz"
2020-02-20 17:17:10 +03:00
```
2024-05-07 20:04:16 +03:00
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo bar baz
2024-04-24 18:49:03 +03:00
bar : Text
bar = "alices bar"
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
baz : Text
baz = "bobs baz"
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
foo =
use Text ++
2024-05-07 20:04:16 +03:00
"foo" ++ " - " ++ bar ++ " - " ++ baz
2024-09-05 17:44:48 +03:00
scratch/alice> display foo
2024-05-07 20:04:16 +03:00
"foo - alices bar - bobs baz"
2021-07-29 06:06:32 +03:00
2024-04-24 18:49:03 +03:00
```
## Propagating an update to an update
2021-07-29 06:06:32 +03:00
2024-05-07 20:04:16 +03:00
Of course, it's also possible for Alice's update to propagate to one of Bob's updates. In this example, `foo` depends on `bar` which depends on `baz`. Alice updates `baz`, propagating to `bar` and `foo`, while Bob updates `bar` (to something that still depends on `foo`), propagating to `baz`. The merged result will have Alice's update to `foo` incorporated into Bob's updated `bar`, and both updates will propagate to `baz`.
2021-07-29 06:06:32 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
2024-05-07 20:04:16 +03:00
foo = "old foo" ++ " - " ++ bar
2024-04-24 18:49:03 +03:00
bar : Text
2024-05-07 20:04:16 +03:00
bar = "old bar" ++ " - " ++ baz
2021-07-29 06:06:32 +03:00
2024-04-24 18:49:03 +03:00
baz : Text
baz = "old baz"
2021-07-29 06:06:32 +03:00
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> display foo
2024-01-09 01:12:01 +03:00
2024-05-07 20:04:16 +03:00
"old foo - old bar - old baz"
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
Alice's updates:
``` unison
2024-05-07 20:04:16 +03:00
baz : Text
baz = "alices baz"
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> display foo
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
"old foo - old bar - alices baz"
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
```
Bob's updates:
``` unison
2024-05-07 20:04:16 +03:00
bar : Text
bar = "bobs bar" ++ " - " ++ baz
```
2024-04-24 18:49:03 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> display foo
2021-07-29 06:06:32 +03:00
2024-05-07 20:04:16 +03:00
"old foo - bobs bar - old baz"
2021-07-29 06:06:32 +03:00
2024-05-07 20:04:16 +03:00
```
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo bar baz
2024-04-24 18:49:03 +03:00
bar : Text
bar =
use Text ++
2024-05-07 20:04:16 +03:00
"bobs bar" ++ " - " ++ baz
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
baz : Text
baz = "alices baz"
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
foo =
use Text ++
2024-05-07 20:04:16 +03:00
"old foo" ++ " - " ++ bar
2024-09-05 17:44:48 +03:00
scratch/alice> display foo
2024-05-07 20:04:16 +03:00
"old foo - bobs bar - alices baz"
2024-04-24 18:49:03 +03:00
2021-07-29 06:06:32 +03:00
```
2024-04-24 18:49:03 +03:00
## Update + delete isn't (currently) a conflict
2024-05-07 20:04:16 +03:00
We don't currently consider "update + delete" a conflict like Git does. In this situation, the delete is just ignored, allowing the update to proceed.
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "old foo"
2021-07-29 06:06:32 +03:00
```
2024-05-07 20:04:16 +03:00
Alice's updates:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alices foo"
2021-07-29 06:06:32 +03:00
```
2024-05-07 20:04:16 +03:00
Bob's changes:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> delete.term foo
2024-04-24 18:49:03 +03:00
Done.
2024-05-07 20:04:16 +03:00
```
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alices foo"
2021-07-29 06:06:32 +03:00
2024-05-01 19:06:59 +03:00
```
2024-05-07 20:04:16 +03:00
In a future version, we'd like to give the user a warning at least.
2024-05-01 19:06:59 +03:00
2024-05-07 20:04:16 +03:00
## Library dependencies don't create merge conflicts
2024-05-01 19:06:59 +03:00
2024-05-07 20:04:16 +03:00
Library dependencies don't cause merge conflicts, the library dependencies are just unioned together. If two library dependencies have the same name but different namespace hashes, then the merge algorithm makes up two fresh names.
2024-05-01 19:06:59 +03:00
2024-05-07 20:04:16 +03:00
Alice's adds:
``` unison
2024-05-01 19:06:59 +03:00
lib.alice.foo : Nat
lib.alice.foo = 17
lib.bothSame.bar : Nat
lib.bothSame.bar = 18
lib.bothDifferent.baz : Nat
lib.bothDifferent.baz = 19
```
2024-05-07 20:04:16 +03:00
Bob's adds:
``` unison
2024-05-01 19:06:59 +03:00
lib.bob.foo : Nat
lib.bob.foo = 20
lib.bothSame.bar : Nat
lib.bothSame.bar = 18
lib.bothDifferent.baz : Nat
lib.bothDifferent.baz = 21
```
2024-05-07 20:04:16 +03:00
Merge result:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-05-01 19:06:59 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2024-05-01 19:06:59 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo bar baz
2024-05-01 19:06:59 +03:00
lib.alice.foo : Nat
lib.alice.foo = 17
2024-05-01 20:18:46 +03:00
2024-05-01 19:06:59 +03:00
lib.bob.foo : Nat
lib.bob.foo = 20
2024-05-01 20:18:46 +03:00
2024-05-01 19:06:59 +03:00
lib.bothDifferent__0.baz : Nat
lib.bothDifferent__0.baz = 19
2024-05-01 20:18:46 +03:00
2024-05-01 19:06:59 +03:00
lib.bothDifferent__1.baz : Nat
lib.bothDifferent__1.baz = 21
2024-05-01 20:18:46 +03:00
2024-05-01 19:06:59 +03:00
lib.bothSame.bar : Nat
lib.bothSame.bar = 18
2021-07-29 06:06:32 +03:00
```
2024-04-24 18:49:03 +03:00
## No-op merge (Bob = Alice)
If Bob is equals Alice, then merging Bob into Alice looks like this.
2021-07-29 06:06:32 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch alice
2021-07-29 06:06:32 +03:00
2024-04-24 18:49:03 +03:00
Done. I've created the alice branch based off of main.
2024-05-01 20:18:46 +03:00
2024-04-24 19:29:15 +03:00
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /alice`.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/main> branch bob
2024-04-24 18:49:03 +03:00
Done. I've created the bob branch based off of main.
2024-05-01 20:18:46 +03:00
2024-04-24 19:29:15 +03:00
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /bob`.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
😶
2024-05-01 20:18:46 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice was already up-to-date with scratch/bob.
2024-04-24 18:49:03 +03:00
```
## No-op merge (Bob \< Alice)
2024-04-24 18:49:03 +03:00
If Bob is behind Alice, then merging Bob into Alice looks like this.
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch alice
2024-04-24 18:49:03 +03:00
Done. I've created the alice branch based off of main.
2024-05-01 20:18:46 +03:00
2024-04-24 19:29:15 +03:00
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /alice`.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/main> branch bob
2024-04-24 18:49:03 +03:00
Done. I've created the bob branch based off of main.
2024-05-01 20:18:46 +03:00
2024-04-24 19:29:15 +03:00
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /bob`.
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
Alice's addition:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "foo"
```
2021-07-29 06:06:32 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> add
2021-07-29 06:06:32 +03:00
2024-04-24 18:49:03 +03:00
⍟ I've added these definitions:
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
2021-07-29 06:06:32 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2021-07-29 06:06:32 +03:00
2024-04-24 18:49:03 +03:00
😶
2024-05-01 20:18:46 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice was already up-to-date with scratch/bob.
2024-04-24 18:49:03 +03:00
```
## Fast-forward merge (Bob \> Alice)
2024-04-24 18:49:03 +03:00
If Bob is ahead of Alice, then merging Bob into Alice looks like this.
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch alice
2024-04-24 18:49:03 +03:00
Done. I've created the alice branch based off of main.
2024-05-01 20:18:46 +03:00
2024-04-24 19:29:15 +03:00
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /alice`.
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
scratch/main> branch bob
2024-04-24 18:49:03 +03:00
Done. I've created the bob branch based off of main.
2024-05-01 20:18:46 +03:00
2024-04-24 19:29:15 +03:00
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /bob`.
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
Bob's addition:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "foo"
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
2024-04-24 18:49:03 +03:00
⍟ I've added these definitions:
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
foo : Text
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I fast-forward merged scratch/bob into scratch/alice.
2024-04-24 18:49:03 +03:00
```
## No-op merge: merge empty namespace into empty namespace
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch topic
Done. I've created the topic branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /topic`.
2024-09-05 17:44:48 +03:00
scratch/main> merge /topic
😶
2024-09-05 17:44:48 +03:00
scratch/main was already up-to-date with scratch/topic.
2024-04-24 18:49:03 +03:00
```
## Merge failure: someone deleted something
2024-05-07 20:04:16 +03:00
If either Alice or Bob delete something, so long as the other person didn't update it (in which case we ignore the delete, as explained above), then the delete goes through.
This can cause merge failures due to out-of-scope identifiers, and the user may have to do some digging around to find what the deleted name used to refer to. In a future version, we would emit a \[better\] warning at least.
2024-04-24 18:49:03 +03:00
In this example, Alice deletes `foo`, while Bob adds a new dependent of `foo`.
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "foo"
```
2024-05-07 20:04:16 +03:00
Alice's delete:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> delete.term foo
2024-04-24 18:49:03 +03:00
Done.
```
2024-05-07 20:04:16 +03:00
Bob's new code that depends on `foo`:
``` unison
2024-04-24 18:49:03 +03:00
bar : Text
2024-05-07 20:04:16 +03:00
bar = foo ++ " - " ++ foo
2024-04-24 18:49:03 +03:00
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
2024-04-24 18:49:03 +03:00
⍟ I've added these definitions:
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
bar : Text
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-04-24 18:49:03 +03:00
```
``` unison:added-by-ucm scratch.u
2024-04-24 18:49:03 +03:00
bar : Text
bar =
use Text ++
2024-05-07 20:04:16 +03:00
foo ++ " - " ++ foo
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
## Merge failure: type error
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
It may be Alice's and Bob's changes merge together cleanly in the sense that there's no textual conflicts, yet the resulting namespace doesn't typecheck.
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
In this example, Alice updates a `Text` to a `Nat`, while Bob adds a new dependent of the `Text`. Upon merging, propagating Alice's update to Bob's dependent causes a typechecking failure.
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-05-07 20:04:16 +03:00
foo : Text
foo = "foo"
2024-04-24 18:49:03 +03:00
```
2024-05-07 20:04:16 +03:00
Alice's update:
``` unison
2024-05-07 20:04:16 +03:00
foo : Nat
foo = 100
```
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
Bob's new definition:
``` unison
2024-05-07 20:04:16 +03:00
bar : Text
bar = foo ++ " - " ++ foo
```
2024-04-24 18:49:03 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-04-24 18:49:03 +03:00
```
``` unison:added-by-ucm scratch.u
2024-04-24 18:49:03 +03:00
bar : Text
bar =
use Text ++
2024-05-07 20:04:16 +03:00
foo ++ " - " ++ foo
2024-04-30 21:47:39 +03:00
2024-04-24 18:49:03 +03:00
```
## Merge failure: simple term conflict
Alice and Bob may disagree about the definition of a term. In this case, the conflicted term and all of its dependents
are presented to the user to resolve.
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "old foo"
bar : Text
bar = "old bar"
```
2024-05-07 20:04:16 +03:00
Alice's changes:
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alices foo"
bar : Text
bar = "alices bar"
qux : Text
qux = "alices qux depends on alices foo" ++ foo
```
2024-05-07 20:04:16 +03:00
Bob's changes:
2024-04-24 18:49:03 +03:00
``` unison
2024-04-24 18:49:03 +03:00
foo : Text
foo = "bobs foo"
baz : Text
baz = "bobs baz"
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-04-24 18:49:03 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-04-24 18:49:03 +03:00
foo : Text
foo = "alices foo"
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-04-24 18:49:03 +03:00
foo : Text
foo = "bobs foo"
2024-04-30 21:47:39 +03:00
-- The definitions below are not conflicted, but they each depend on one or more
-- conflicted definitions above.
2024-04-24 18:49:03 +03:00
qux : Text
qux =
use Text ++
"alices qux depends on alices foo" ++ foo
2024-04-30 21:47:39 +03:00
2024-04-24 18:49:03 +03:00
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/merge-bob-into-alice> view bar baz
2024-04-24 18:49:03 +03:00
bar : Text
bar = "alices bar"
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
baz : Text
baz = "bobs baz"
```
## Merge failure: simple type conflict
2024-05-07 20:04:16 +03:00
Ditto for types; if the hashes don't match, it's a conflict. In this example, Alice and Bob do different things to the same constructor. However, any explicit changes to the same type will result in a conflict, including changes that could concievably be merged (e.g. Alice and Bob both add a new constructor, or edit different constructors).
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = MkFoo Nat
```
2024-05-07 20:04:16 +03:00
Alice's changes:
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = MkFoo Nat Nat
```
2024-05-07 20:04:16 +03:00
Bob's changes:
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = MkFoo Nat Text
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-04-24 18:49:03 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-04-24 18:49:03 +03:00
type Foo = MkFoo Nat Nat
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-04-24 18:49:03 +03:00
type Foo = MkFoo Nat Text
2024-04-30 21:47:39 +03:00
2024-04-24 18:49:03 +03:00
```
## Merge failure: type-update + constructor-rename conflict
2024-05-07 20:04:16 +03:00
We model the renaming of a type's constructor as an update, so if Alice updates a type and Bob renames one of its constructors (even without changing its structure), we consider it a conflict.
2024-04-24 18:49:03 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = Baz Nat | Qux Text
```
2024-05-07 20:04:16 +03:00
Alice's changes `Baz Nat` to `Baz Nat Nat`
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = Baz Nat Nat | Qux Text
```
2024-05-07 20:04:16 +03:00
Bob's renames `Qux` to `BobQux`:
2024-08-08 18:16:43 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> move.term Foo.Qux Foo.BobQux
2024-04-24 18:49:03 +03:00
2024-08-08 18:16:43 +03:00
Done.
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-04-24 18:49:03 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-10 19:18:17 +03:00
type Foo = Baz Nat Nat | Qux Text
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-08-08 18:16:43 +03:00
type Foo = BobQux Text | Baz Nat
2024-04-30 21:47:39 +03:00
2024-04-24 18:49:03 +03:00
```
## Merge failure: constructor-rename conflict
2024-05-07 20:04:16 +03:00
Here is another example demonstrating that constructor renames are modeled as updates.
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
unique type Foo = Baz Nat | Qux Text
```
2024-05-07 20:04:16 +03:00
Alice's rename:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> move.term Foo.Baz Foo.Alice
2024-05-07 20:04:16 +03:00
Done.
2024-05-07 20:04:16 +03:00
```
Bob's rename:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> move.term Foo.Qux Foo.Bob
Done.
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-10 19:18:17 +03:00
type Foo = Qux Text | Alice Nat
2024-04-30 21:47:39 +03:00
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-05-10 19:18:17 +03:00
type Foo = Bob Text | Baz Nat
2024-04-30 21:47:39 +03:00
2024-05-01 18:56:27 +03:00
```
2024-05-07 20:04:16 +03:00
## Merge failure: non-constructor/constructor conflict
2024-05-01 18:56:27 +03:00
2024-05-07 20:04:16 +03:00
A constructor on one side can conflict with a regular term definition on the other.
2024-05-01 18:56:27 +03:00
2024-05-07 20:04:16 +03:00
Alice's additions:
``` unison
2024-05-01 18:56:27 +03:00
my.cool.thing : Nat
my.cool.thing = 17
```
2024-05-07 20:04:16 +03:00
Bob's additions:
``` unison
2024-05-01 18:56:27 +03:00
unique ability my.cool where
thing : Nat -> Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-05-01 18:56:27 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-05-01 18:56:27 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-01 18:56:27 +03:00
my.cool.thing : Nat
my.cool.thing = 17
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-05-01 18:56:27 +03:00
ability my.cool where thing : Nat ->{cool} Nat
```
2024-05-07 23:36:57 +03:00
## Merge failure: type/type conflict with term/constructor conflict
2024-05-01 18:56:27 +03:00
2024-05-07 23:36:57 +03:00
Here's a subtle situation where a new type is added on each side of the merge, and an existing term is replaced with a constructor of one of the types.
2024-05-01 18:56:27 +03:00
2024-05-07 20:04:16 +03:00
Original branch:
``` unison
2024-05-01 18:56:27 +03:00
Foo.Bar : Nat
Foo.Bar = 17
```
2024-05-07 23:36:57 +03:00
Alice adds this type `Foo` with constructor `Foo.Alice`:
``` unison
2024-05-01 18:56:27 +03:00
unique type Foo = Alice Nat
```
2024-05-07 23:36:57 +03:00
Bob adds the type `Foo` with constructor `Foo.Bar`, replacing the original `Foo.Bar` term:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> delete.term Foo.Bar
2024-05-01 18:56:27 +03:00
Done.
```
``` unison
2024-05-01 18:56:27 +03:00
unique type Foo = Bar Nat Nat
```
2024-05-07 23:36:57 +03:00
These won't cleanly merge.
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-05-01 18:56:27 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-05-01 18:56:27 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-01 18:56:27 +03:00
Foo.Bar : Nat
Foo.Bar = 17
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-01 18:56:27 +03:00
type Foo = Alice Nat
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-05-01 18:56:27 +03:00
type Foo = Bar Nat Nat
```
2024-05-07 23:36:57 +03:00
Here's a more involved example that demonstrates the same idea.
2024-05-01 18:56:27 +03:00
In the LCA, we have a type with two constructors, and some term.
``` unison
2024-05-01 18:56:27 +03:00
unique type Foo
= Bar.Baz Nat
| Bar.Qux Nat Nat
Foo.Bar.Hello : Nat
Foo.Bar.Hello = 17
```
Alice deletes this type entirely, and repurposes its constructor names for other terms. She also updates the term.
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> view Foo.Bar.Baz Foo.Bar.Qux Foo.Bar.Hello
2024-05-01 18:56:27 +03:00
2024-05-07 20:04:16 +03:00
Foo.Bar.Baz : Nat
Foo.Bar.Baz = 100
2024-05-01 20:18:46 +03:00
2024-05-07 20:04:16 +03:00
Foo.Bar.Hello : Nat
Foo.Bar.Hello = 18
2024-05-01 20:18:46 +03:00
2024-05-07 20:04:16 +03:00
Foo.Bar.Qux : Nat
Foo.Bar.Qux = 200
2024-05-01 18:56:27 +03:00
```
2024-05-07 20:04:16 +03:00
Bob, meanwhile, first deletes the term, then sort of deletes the type and re-adds it under another name, but one constructor's fully qualified names doesn't actually change. The other constructor reuses the name of the deleted term.
2024-05-01 18:56:27 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> view Foo.Bar
2024-05-01 18:56:27 +03:00
type Foo.Bar = Baz Nat | Hello Nat Nat
2024-05-01 18:56:27 +03:00
```
2024-05-07 20:04:16 +03:00
At this point, Bob and alice have both updated the name `Foo.Bar.Hello` in different ways, so that's a conflict. Therefore, Bob's entire type (`Foo.Bar` with constructors `Foo.Bar.Baz` and `Foo.Bar.Hello`) gets rendered into the scratch file.
2024-05-01 18:56:27 +03:00
2024-05-07 20:04:16 +03:00
Notably, Alice's "unconflicted" update on the name "Foo.Bar.Baz" (because she changed its hash and Bob didn't touch it) is nonetheless considered conflicted with Bob's "Foo.Bar.Baz".
2024-05-01 18:56:27 +03:00
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-05-01 18:56:27 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-05-01 18:56:27 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-01 18:56:27 +03:00
Foo.Bar.Baz : Nat
Foo.Bar.Baz = 100
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-01 18:56:27 +03:00
Foo.Bar.Hello : Nat
Foo.Bar.Hello = 18
2024-09-05 17:44:48 +03:00
-- scratch/bob
type Foo.Bar = Baz Nat | Hello Nat Nat
2024-05-01 18:56:27 +03:00
```
## Merge algorithm quirk: add/add unique types
Currently, two unique types created by Alice and Bob will be considered in conflict, even if they "look the same".
The result may be confusing to a user a file containing two identical-looking copies of a unique type is rendered,
which is a parse error.
2024-05-07 20:04:16 +03:00
We will resolve this situation automatically in a future version.
2024-05-07 20:04:16 +03:00
Alice's additions:
``` unison
unique type Foo = Bar
alice : Foo -> Nat
alice _ = 18
```
2024-05-07 20:04:16 +03:00
Bob's additions:
``` unison
unique type Foo = Bar
bob : Foo -> Nat
bob _ = 19
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
type Foo
= Bar
2024-09-05 17:44:48 +03:00
-- scratch/bob
type Foo
= Bar
-- The definitions below are not conflicted, but they each depend on one or more
-- conflicted definitions above.
alice : Foo -> Nat
alice _ = 18
bob : Foo -> Nat
bob _ = 19
```
2024-06-13 15:29:02 +03:00
## `merge.commit` example (success)
2024-05-20 21:21:06 +03:00
2024-06-11 21:15:30 +03:00
After merge conflicts are resolved, you can use `merge.commit` rather than `switch` + `merge` + `branch.delete` to
"commit" your changes.
2024-05-20 21:21:06 +03:00
Original branch:
``` unison
2024-05-20 21:21:06 +03:00
foo : Text
foo = "old foo"
```
Alice's changes:
``` unison
2024-05-20 21:21:06 +03:00
foo : Text
foo = "alices foo"
```
Bob's changes:
``` unison
2024-05-20 21:21:06 +03:00
foo : Text
foo = "bobs foo"
```
Attempt to merge:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-05-20 21:21:06 +03:00
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
2024-05-20 21:21:06 +03:00
However, I've added the definitions that need attention to the
top of scratch.u.
2024-06-11 21:15:30 +03:00
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
2024-05-20 21:21:06 +03:00
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
2024-05-20 21:21:06 +03:00
foo : Text
foo = "alices foo"
2024-09-05 17:44:48 +03:00
-- scratch/bob
2024-05-20 21:21:06 +03:00
foo : Text
foo = "bobs foo"
```
Resolve conflicts and commit:
``` unison
2024-05-20 21:21:06 +03:00
foo : Text
foo = "alice and bobs foo"
```
``` ucm
2024-05-20 21:21:06 +03:00
Loading changes detected in scratch.u.
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:
2024-05-20 21:21:06 +03:00
foo : Text
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/merge-bob-into-alice> update
2024-05-20 21:21:06 +03:00
Okay, I'm searching the branch for code that needs to be
updated...
Done.
2024-09-05 17:44:48 +03:00
scratch/merge-bob-into-alice> merge.commit
2024-06-11 21:15:30 +03:00
2024-09-05 17:44:48 +03:00
I fast-forward merged scratch/merge-bob-into-alice into
scratch/alice.
2024-05-20 21:21:06 +03:00
2024-09-05 17:44:48 +03:00
scratch/alice> view foo
2024-05-20 21:21:06 +03:00
foo : Text
foo = "alice and bobs foo"
2024-09-05 17:44:48 +03:00
scratch/alice> branches
2024-05-20 21:21:06 +03:00
Branch Remote branch
1. alice
2. bob
3. main
2024-06-13 15:29:02 +03:00
```
## `merge.commit` example (failure)
`merge.commit` can only be run on a "merge branch".
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch topic
2024-06-13 15:29:02 +03:00
Done. I've created the topic branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /topic`.
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/topic> merge.commit
2024-06-13 15:29:02 +03:00
It doesn't look like there's a merge in progress.
2024-05-20 21:21:06 +03:00
```
2024-04-24 18:49:03 +03:00
## Precondition violations
There are a number of conditions under which we can't perform a merge, and the user will have to fix up the namespace(s) manually before attempting to merge again.
2024-04-24 18:49:03 +03:00
### Conflicted aliases
If `foo` and `bar` are aliases in the nearest common ancestor, but not in Alice's branch, then we don't know whether to update Bob's dependents to Alice's `foo` or Alice's `bar` (and vice-versa).
2024-04-24 18:49:03 +03:00
Original branch:
``` unison
2024-04-24 18:49:03 +03:00
foo : Nat
foo = 100
bar : Nat
bar = 100
```
Alice's updates:
``` unison
2024-04-24 18:49:03 +03:00
foo : Nat
foo = 200
bar : Nat
bar = 300
```
Bob's addition:
``` unison
2024-04-24 18:49:03 +03:00
baz : Text
baz = "baz"
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
Sorry, I wasn't able to perform the merge:
On the merge ancestor, bar and foo were aliases for the same
2024-09-05 17:44:48 +03:00
term, but on scratch/alice the names have different
definitions currently. I'd need just a single new definition
to use in their dependents when I merge.
2024-09-05 17:44:48 +03:00
Please fix up scratch/alice to resolve this. For example,
* `update` the definitions to be the same again, so that
there's nothing for me to decide.
* `move` or `delete` all but one of the definitions; I'll
use the remaining name when propagating updates. (You can
`move` it back after the merge.)
and then try merging again.
2024-04-24 18:49:03 +03:00
```
### Conflict involving builtin
We don't have a way of rendering a builtin in a scratch file, where users resolve merge conflicts. Thus, if there is a
conflict involving a builtin, we can't perform a merge.
One way to fix this in the future would be to introduce a syntax for defining aliases in the scratch file.
2024-04-24 18:49:03 +03:00
Alice's branch:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> alias.type lib.builtins.Nat MyNat
2024-04-24 18:49:03 +03:00
Done.
```
Bob's branch:
``` unison
2024-04-24 18:49:03 +03:00
unique type MyNat = MyNat Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
Sorry, I wasn't able to perform the merge:
There's a merge conflict on type MyNat, but it's a builtin on
one or both branches. I can't yet handle merge conflicts
involving builtins.
Please eliminate this conflict by updating one branch or the
other, making MyNat the same on both branches, or making
neither of them a builtin, and then try the merge again.
2024-04-24 18:49:03 +03:00
```
### Constructor alias
Each naming of a decl may not have more than one name for each constructor, within the decl's namespace.
2024-04-24 18:49:03 +03:00
Alice's branch:
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = Bar
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> alias.term Foo.Bar Foo.some.other.Alias
2024-04-24 18:49:03 +03:00
Done.
```
Bob's branch:
``` unison
bob : Nat
bob = 100
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
Sorry, I wasn't able to perform the merge:
2024-09-05 17:44:48 +03:00
On scratch/alice, the type Foo has a constructor with multiple
names, and I can't perform a merge in this situation:
* Foo.Bar
* Foo.some.other.Alias
Please delete all but one name for each constructor, and then
try merging again.
2024-04-24 18:49:03 +03:00
```
### Missing constructor name
Each naming of a decl must have a name for each constructor, within the decl's namespace.
2024-04-24 18:49:03 +03:00
Alice's branch:
``` unison
2024-04-24 18:49:03 +03:00
unique type Foo = Bar
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> delete.term Foo.Bar
2024-04-24 18:49:03 +03:00
Done.
```
Bob's branch:
``` unison
bob : Nat
bob = 100
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
Sorry, I wasn't able to perform the merge:
2024-09-05 17:44:48 +03:00
On scratch/alice, the type Foo has some constructors with
missing names, and I can't perform a merge in this situation.
You can use `view Foo` and
`alias.term <hash> Foo.<ConstructorName>` to give names to
each unnamed constructor, and then try the merge again.
2024-04-24 18:49:03 +03:00
```
### Nested decl alias
A decl cannot be aliased within the namespace of another of its aliased.
2024-04-24 18:49:03 +03:00
Alice's branch:
``` unison
2024-04-24 18:49:03 +03:00
structural type A = B Nat | C Nat Nat
structural type A.inner.X = Y Nat | Z Nat Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> names A
2024-04-24 18:49:03 +03:00
Type
Hash: #65mdg7015r
Names: A A.inner.X
```
Bob's branch:
``` unison
bob : Nat
bob = 100
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
2024-09-05 17:44:48 +03:00
On scratch/alice, the type A.inner.X is an alias of A. I'm not
able to perform a merge when a type exists nested under an
alias of itself. Please separate them or delete one copy, and
then try merging again.
2024-04-24 18:49:03 +03:00
```
### Stray constructor alias
Constructors may only exist within the corresponding decl's namespace.
2024-04-24 18:49:03 +03:00
Alice's branch:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> add
2024-04-24 18:49:03 +03:00
⍟ I've added these definitions:
2024-05-01 20:18:46 +03:00
2024-04-24 18:49:03 +03:00
type Foo
2024-09-05 17:44:48 +03:00
scratch/alice> alias.term Foo.Bar AliasOutsideFooNamespace
2024-04-24 18:49:03 +03:00
Done.
```
Bob's branch:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
⍟ I've added these definitions:
bob : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge bob
2024-04-24 18:49:03 +03:00
Sorry, I wasn't able to perform the merge, because I need all
constructor names to be nested somewhere beneath the
corresponding type name.
2024-09-05 17:44:48 +03:00
On scratch/alice, the constructor AliasOutsideFooNamespace is
not nested beneath the corresponding type name. Please either
use `move` to move it, or if it's an extra copy, you can
simply `delete` it. Then try the merge again.
2024-04-24 18:49:03 +03:00
```
### Term or type in `lib`
By convention, `lib` can only namespaces; each of these represents a library dependencies. Individual terms and types are not allowed at the top level of `lib`.
2024-04-24 18:49:03 +03:00
Alice's branch:
``` unison
2024-04-24 18:49:03 +03:00
lib.foo : Nat
lib.foo = 1
```
Bob's branch:
``` unison
bob : Nat
bob = 100
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-04-24 18:49:03 +03:00
Sorry, I wasn't able to perform the merge:
2024-09-05 17:44:48 +03:00
On scratch/alice, there's a type or term at the top level of
the `lib` namespace, where I only expect to find subnamespaces
representing library dependencies.
Please move or remove it and then try merging again.
2021-07-29 06:06:32 +03:00
```
2024-05-29 19:41:59 +03:00
## LCA precondition violations
The LCA is not subject to most precondition violations, which is good, because the user can't easily manipulate it\!
2024-05-29 19:41:59 +03:00
Here's an example. We'll delete a constructor name from the LCA and still be able to merge Alice and Bob's stuff
together.
LCA:
``` unison
2024-05-29 19:41:59 +03:00
structural type Foo = Bar Nat | Baz Nat Nat
```
``` ucm
2024-05-29 19:41:59 +03:00
Loading changes detected in scratch.u.
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`:
structural type Foo
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> add
2024-05-29 19:41:59 +03:00
⍟ I've added these definitions:
structural type Foo
2024-09-05 17:44:48 +03:00
scratch/main> delete.term Foo.Baz
2024-05-29 19:41:59 +03:00
Done.
```
Alice's branch:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch alice
2024-05-29 19:41:59 +03:00
Done. I've created the alice branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /alice`.
2024-09-05 17:44:48 +03:00
scratch/alice> delete.type Foo
2024-05-29 19:41:59 +03:00
Done.
2024-09-05 17:44:48 +03:00
scratch/alice> delete.term Foo.Bar
2024-05-29 19:41:59 +03:00
Done.
```
``` unison
2024-05-29 19:41:59 +03:00
alice : Nat
alice = 100
```
``` ucm
2024-05-29 19:41:59 +03:00
Loading changes detected in scratch.u.
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`:
alice : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> add
2024-05-29 19:41:59 +03:00
⍟ I've added these definitions:
alice : Nat
```
Bob's branch:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> branch bob
2024-05-29 19:41:59 +03:00
Done. I've created the bob branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /bob`.
2024-09-05 17:44:48 +03:00
scratch/bob> delete.type Foo
2024-05-29 19:41:59 +03:00
Done.
2024-09-05 17:44:48 +03:00
scratch/bob> delete.term Foo.Bar
2024-05-29 19:41:59 +03:00
Done.
```
``` unison
2024-05-29 19:41:59 +03:00
bob : Nat
bob = 101
```
``` ucm
2024-05-29 19:41:59 +03:00
Loading changes detected in scratch.u.
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`:
bob : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
2024-05-29 19:41:59 +03:00
⍟ I've added these definitions:
bob : Nat
```
Now we merge:
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-05-29 19:41:59 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2021-07-29 06:06:32 +03:00
```
2024-06-10 20:56:12 +03:00
## Regression tests
### Delete one alias and update the other
``` unison
2024-06-10 20:56:12 +03:00
foo = 17
bar = 17
```
``` ucm
2024-06-10 20:56:12 +03:00
Loading changes detected in scratch.u.
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`:
bar : Nat
foo : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> add
2024-06-10 20:56:12 +03:00
⍟ I've added these definitions:
bar : Nat
foo : Nat
2024-09-05 17:44:48 +03:00
scratch/main> branch alice
2024-06-10 20:56:12 +03:00
Done. I've created the alice branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /alice`.
2024-09-05 17:44:48 +03:00
scratch/alice> delete.term bar
2024-06-10 20:56:12 +03:00
Done.
```
``` unison
2024-06-10 20:56:12 +03:00
foo = 18
```
``` ucm
2024-06-10 20:56:12 +03:00
Loading changes detected in scratch.u.
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
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> update
2024-06-10 20:56:12 +03:00
Okay, I'm searching the branch for code that needs to be
updated...
Done.
2024-09-05 17:44:48 +03:00
scratch/main> branch bob
2024-06-10 20:56:12 +03:00
Done. I've created the bob branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /bob`.
```
``` unison
2024-06-10 20:56:12 +03:00
bob = 101
```
``` ucm
2024-06-10 20:56:12 +03:00
Loading changes detected in scratch.u.
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`:
bob : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
2024-06-10 20:56:12 +03:00
⍟ I've added these definitions:
bob : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-06-10 20:56:12 +03:00
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/alice.
2024-06-10 20:56:12 +03:00
```
### Delete a constructor
``` unison
type Foo = Bar | Baz
```
``` ucm
Loading changes detected in scratch.u.
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`:
type Foo
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> add
⍟ I've added these definitions:
type Foo
2024-09-05 17:44:48 +03:00
scratch/main> branch topic
Done. I've created the topic branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /topic`.
```
``` unison
boop = "boop"
```
``` ucm
Loading changes detected in scratch.u.
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`:
boop : Text
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/topic> add
⍟ I've added these definitions:
boop : Text
```
``` unison
type Foo = Bar
```
``` ucm
Loading changes detected in scratch.u.
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:
type Foo
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> update
Okay, I'm searching the branch for code that needs to be
updated...
Done.
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/main> merge topic
2024-09-05 17:44:48 +03:00
I merged scratch/topic into scratch/main.
2024-09-05 17:44:48 +03:00
scratch/main> view Foo
type Foo = Bar
```
### Dependent that doesn't need to be in the file
This test demonstrates a bug.
In the LCA, we have `foo` with dependent `bar`, and `baz`.
``` unison
foo : Nat
foo = 17
bar : Nat
bar = foo + foo
baz : Text
baz = "lca"
```
``` ucm
Loading changes detected in scratch.u.
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`:
bar : Nat
baz : Text
foo : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> add
⍟ I've added these definitions:
bar : Nat
baz : Text
foo : Nat
2024-09-05 17:44:48 +03:00
scratch/alice> branch bob
Done. I've created the bob branch based off of alice.
Tip: To merge your work back into the alice branch, first
`switch /alice` then `merge /bob`.
```
On Bob, we update `baz` to "bob".
``` unison
baz : Text
baz = "bob"
```
``` ucm
Loading changes detected in scratch.u.
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:
baz : Text
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> update
Okay, I'm searching the branch for code that needs to be
updated...
Done.
```
On Alice, we update `baz` to "alice" (conflict), but also update `foo` (unconflicted), which propagates to `bar`.
``` unison
foo : Nat
foo = 18
baz : Text
baz = "alice"
```
``` ucm
Loading changes detected in scratch.u.
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:
baz : Text
foo : Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> update
Okay, I'm searching the branch for code that needs to be
updated...
That's done. Now I'm making sure everything typechecks...
Everything typechecks, so I'm saving the results...
Done.
```
When we try to merge Bob into Alice, we should see both versions of `baz`, with Alice's unconflicted `foo` and `bar` in
the underlying namespace.
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> merge /bob
2024-09-05 17:44:48 +03:00
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
```
``` unison:added-by-ucm scratch.u
2024-09-05 17:44:48 +03:00
-- scratch/alice
baz : Text
baz = "alice"
2024-09-05 17:44:48 +03:00
-- scratch/bob
baz : Text
baz = "bob"
-- The definitions below are not conflicted, but they each depend on one or more
-- conflicted definitions above.
bar : Nat
bar =
use Nat +
foo + foo
```
But `bar` was put into the scratch file instead.
### Merge loop test
This tests for regressions of https://github.com/unisonweb/unison/issues/1276 where trivial merges cause loops in the
history.
Let's make three identical namespaces with different histories:
``` unison
a = 1
```
``` ucm
Loading changes detected in scratch.u.
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 : ##Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> add
⍟ I've added these definitions:
a : ##Nat
```
``` unison
b = 2
```
``` ucm
Loading changes detected in scratch.u.
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`:
b : ##Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/alice> add
⍟ I've added these definitions:
b : ##Nat
```
``` unison
b = 2
```
``` ucm
Loading changes detected in scratch.u.
I found and typechecked the definitions in scratch.u. This
file has been previously added to the codebase.
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
⍟ I've added these definitions:
b : ##Nat
```
``` unison
a = 1
```
``` ucm
Loading changes detected in scratch.u.
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 : ##Nat
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/bob> add
⍟ I've added these definitions:
a : ##Nat
```
``` unison
a = 1
b = 2
```
``` ucm
Loading changes detected in scratch.u.
I found and typechecked the definitions in scratch.u. This
file has been previously added to the codebase.
```
``` ucm
2024-09-05 17:44:48 +03:00
scratch/carol> add
⍟ I've added these definitions:
a : ##Nat
b : ##Nat
2024-09-05 17:44:48 +03:00
scratch/bob> merge /alice
2024-09-05 17:44:48 +03:00
I merged scratch/alice into scratch/bob.
2024-09-05 17:44:48 +03:00
scratch/carol> merge /bob
2024-09-05 17:44:48 +03:00
I merged scratch/bob into scratch/carol.
2024-09-05 17:44:48 +03:00
scratch/carol> history
Note: The most recent namespace hash is immediately below this
message.
This segment of history starts with a merge. Use
`history #som3n4m3space` to view history starting from a given
namespace hash.
⊙ 1. #b7fr6ifj87
2. #9npggauqo9
3. #dm4u1eokg1
```
2024-07-09 21:10:53 +03:00
### Variables named `_`
This test demonstrates a change in syntactic hashing that fixed a bug due to auto-generated variable names for ignored
results.
``` unison
2024-07-09 21:10:53 +03:00
ignore : a -> ()
ignore _ = ()
foo : Nat
foo = 18
bar : Nat
bar =
ignore "hi"
foo + foo
```
``` ucm
2024-07-09 21:10:53 +03:00
Loading changes detected in scratch.u.
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`:
bar : Nat
foo : Nat
ignore : a -> ()
```
``` ucm
2024-07-09 21:10:53 +03:00
scratch/alice> add
⍟ I've added these definitions:
bar : Nat
foo : Nat
ignore : a -> ()
scratch/alice> branch bob
Done. I've created the bob branch based off of alice.
Tip: To merge your work back into the alice branch, first
`switch /alice` then `merge /bob`.
```
``` unison
2024-07-09 21:10:53 +03:00
bar : Nat
bar =
ignore "hi"
foo + foo + foo
```
``` ucm
2024-07-09 21:10:53 +03:00
Loading changes detected in scratch.u.
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:
bar : Nat
```
``` ucm
2024-07-09 21:10:53 +03:00
scratch/bob> update
Okay, I'm searching the branch for code that needs to be
updated...
Done.
```
Previously, this update to `foo` would also cause a "real update" on `bar`, its dependent. Now it doesn't, so the merge
will succeed.
``` unison
2024-07-09 21:10:53 +03:00
foo : Nat
foo = 19
```
``` ucm
2024-07-09 21:10:53 +03:00
Loading changes detected in scratch.u.
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
```
``` ucm
2024-07-09 21:10:53 +03:00
scratch/alice> update
Okay, I'm searching the branch for code that needs to be
updated...
That's done. Now I'm making sure everything typechecks...
Everything typechecks, so I'm saving the results...
Done.
```
``` ucm
2024-07-09 21:10:53 +03:00
scratch/alice> merge /bob
I merged scratch/bob into scratch/alice.
```
2024-09-05 17:44:48 +03:00
### Unique type GUID reuse
Previously, a merge branch would not include any dependents in the namespace, but that resulted in dependent unique
types' GUIDs being regenerated.
``` unison
type Foo = Lca
type Bar = MkBar Foo
```
``` ucm
Loading changes detected in scratch.u.
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`:
type Bar
type Foo
```
``` ucm
scratch/main> add
⍟ I've added these definitions:
type Bar
type Foo
scratch/main> branch alice
Done. I've created the alice branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /alice`.
scratch/alice> move.term Foo.Lca Foo.Alice
Done.
scratch/main> branch bob
Done. I've created the bob branch based off of main.
Tip: To merge your work back into the main branch, first
`switch /main` then `merge /bob`.
scratch/bob> move.term Foo.Lca Foo.Bob
Done.
```
``` ucm
scratch/alice> merge /bob
I couldn't automatically merge scratch/bob into scratch/alice.
However, I've added the definitions that need attention to the
top of scratch.u.
When you're done, you can run
merge.commit
to merge your changes back into alice and delete the temporary
branch. Or, if you decide to cancel the merge instead, you can
run
delete.branch /merge-bob-into-alice
to delete the temporary branch and switch back to alice.
```
``` unison:added-by-ucm scratch.u
-- scratch/alice
type Foo
= Alice
-- scratch/bob
type Foo
= Bob
-- The definitions below are not conflicted, but they each depend on one or more
-- conflicted definitions above.
type Bar
= MkBar Foo
```
``` ucm
```
``` unison
type Foo = Merged
type Bar = MkBar Foo
```
``` ucm
Loading changes detected in scratch.u.
I found and typechecked the definitions in scratch.u. This
file has been previously added to the codebase.
2024-09-05 17:44:48 +03:00
```
``` ucm
scratch/merge-bob-into-alice> update
Okay, I'm searching the branch for code that needs to be
updated...
Done.
scratch/merge-bob-into-alice> names Bar
Type
Hash: #h3af39sae7
2024-09-05 17:44:48 +03:00
Names: Bar
scratch/alice> names Bar
Type
Hash: #h3af39sae7
Names: Bar
```