Skip to content

Commit 5d8b19a

Browse files
committed
[uploadChangeset] handle merge conflicts
1 parent bf5b770 commit 5d8b19a

5 files changed

Lines changed: 887 additions & 37 deletions

File tree

examples/uploadChangeset.md

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ await uploadChangeset(
2020
{
2121
// optional callbacks and options, see below for details
2222
onChunk: () => {},
23+
onAutomaticConflict: () => {},
24+
onManualConflict: () => {},
2325
}
2426
);
2527
```
@@ -121,6 +123,90 @@ await uploadChangeset(changesetTags, diff, {
121123
});
122124
```
123125

126+
### onAutomaticConflict
127+
128+
When uploading a changeset, a [merge conflict](https://en.wikipedia.org/wiki/Edit_conflict) could occur if two users edit the same feature at the same time.
129+
130+
When this happens, this library might be able to automatically resolve the conflict, if the conflict is simple enough.
131+
For example, if both users deleted the same feature, then that conflict will be automatically resolved by this library.
132+
133+
When an merge conflict occurs that can be automatically resolved, the library will call a callback called `onAutomaticConflict`.
134+
135+
The callback is invoked **for every conflicting feature**.
136+
137+
- If there is no callback, `onManualConflict` will be called instead
138+
- If the callback returns `false`, then `onManualConflict` will be called instead
139+
- If the callback returns an object, then the upload continues.
140+
- You can optionally return an object of changeset `Tags`. If provided, then the changeset tags are updated to match the tags that you provided.
141+
142+
> [!NOTE]
143+
> If you do not define `onAutomaticConflict` and do not define `onManualConflict` (see below),
144+
> then any merge conflict will cause `uploadChangeset` to throw an error.
145+
146+
### onManualConflict
147+
148+
Some conflicts are too complicated to be automatically resolved.
149+
150+
For example, <kbd>you</kbd> add a tag to a feature at the same time that <kbd>other user</kbd> deletes the feature.
151+
152+
In this case, your code needs to decide what do to. Options include:
153+
154+
- keeping <kbd>you</kbd>r changes (the `local` version)
155+
- keeping <kbd>other user</kbd>'s changes (the `remote` version)
156+
- merging the changes automatically using your own logic.
157+
- prompting the user to compare the diff and select who's version should be kept.
158+
159+
The `onManualConflict` callback is invoked if a merge conflict occurs while uploading, and that conflict is too complex to be resolved automatically by this library.
160+
161+
The callback is invoked **for every conflicting feature**.
162+
163+
- If there is no callback, then the upload fails.
164+
- If the callback returns `false`, then the upload fails.
165+
- If the callback returns a merged object, then that merged
166+
object is used.
167+
- You can directly return the `local` or `remote` version,
168+
or merge the two yourself and return the merged version.
169+
- You can also optionally return an object of changeset
170+
`Tags`. If provided, then the changeset tags are updated
171+
to match the tags that you provided.
172+
173+
> [!NOTE]
174+
> If you do not define `onManualConflict` and do not define `onAutomaticConflict` (see above),
175+
> then any merge conflict will cause `uploadChangeset` to throw an error.
176+
177+
## maxRetries
178+
179+
If a merge conflict occurs between <kbd>you</kbd> and <kbd>other user</kbd>, it might take <kbd>you</kbd> several minutes to resolve the conflicts using your UI.
180+
During that time, <kbd>other user</kbd> might make more edits, and cause more conflicts.
181+
182+
Example:
183+
184+
```mermaid
185+
gitGraph
186+
commit id: "v1"
187+
branch local
188+
checkout local
189+
checkout main
190+
commit id: "v2 (other user)"
191+
checkout local
192+
commit id: "v2 (you)"
193+
merge main
194+
checkout main
195+
commit id: "v3 (other user)"
196+
merge local
197+
```
198+
199+
In this example graph, <kbd>you</kbd> and <kbd>other user</kbd> both created `v2`, which is a conflict.
200+
While <kbd>you</kbd> are resolving conflicts, <kbd>other user</kbd> has published `v3`.
201+
202+
&nbsp;
203+
204+
If this happens, the 2nd attempt to upload your changes will also fail.
205+
Conflict resolution will need to run again, then the library will try to upload your changes for the 3rd time.
206+
207+
Although this case is extremely unlikely, it could theoretically continue on forever.
208+
The option `maxRetries` specifies how many times this should be retried. By default, it is set to `3`.
209+
124210
### onProgress
125211

126212
`onProgress` is a callback function which is called whenever the upload progress changes.
@@ -135,3 +221,4 @@ It is called with an object parameter:
135221
```
136222

137223
`step` is a number from `0` to `total` which could be used to render a progress bar.
224+
total` might change during the upload, for example, if merge conflicts are encountered, and extra steps are required.

0 commit comments

Comments
 (0)