Skip to content

Commit 2cc4781

Browse files
committed
Fix merging: Do not sync if there are no changes
1 parent 5d40163 commit 2cc4781

1 file changed

Lines changed: 21 additions & 44 deletions

File tree

src/vs/workbench/services/userData/common/settingsSync.ts

Lines changed: 21 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -216,66 +216,43 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
216216
}
217217

218218
if (fileContent && remoteUserData) {
219-
220219
const localContent: string = fileContent.value.toString();
221220
const remoteContent: string = remoteUserData.content;
222221
const lastSyncData = this.getLastSyncUserData();
223-
224-
// Already in Sync.
225-
if (localContent === remoteUserData.content) {
226-
this.logService.trace('Settings Sync: Settings file and remote contents are in sync.');
227-
settingsPreview = localContent;
228-
return { settingsPreview, hasLocalChanged, hasRemoteChanged, hasConflicts };
229-
}
230-
231-
// First time Sync to Local
232-
if (!lastSyncData) {
233-
this.logService.trace('Settings Sync: Syncing remote contents with settings file for the first time.');
234-
hasLocalChanged = hasRemoteChanged = true;
235-
const mergeResult = this.mergeContents(localContent, remoteContent, null);
236-
return { settingsPreview: mergeResult.settingsPreview, hasLocalChanged, hasRemoteChanged, hasConflicts: mergeResult.hasConflicts };
237-
}
238-
239-
// Remote has moved forward
240-
if (remoteUserData.ref !== lastSyncData.ref) {
241-
this.logService.trace('Settings Sync: Remote contents have changed. Merge and Sync.');
242-
hasLocalChanged = true;
243-
hasRemoteChanged = lastSyncData.content !== localContent;
244-
const mergeResult = this.mergeContents(localContent, remoteContent, lastSyncData.content);
245-
return { settingsPreview: mergeResult.settingsPreview, hasLocalChanged, hasRemoteChanged, hasConflicts: mergeResult.hasConflicts };
246-
}
247-
248-
// Remote data is same as last synced data
249-
if (lastSyncData.ref === remoteUserData.ref) {
250-
251-
// Local contents are same as last synced data. No op.
252-
if (lastSyncData.content === localContent) {
253-
this.logService.trace('Settings Sync: Settings file and remote contents have not changed. So no sync needed.');
222+
if (!lastSyncData // First time sync
223+
|| lastSyncData.content !== localContent // Local has moved forwarded
224+
|| lastSyncData.content !== remoteContent // Remote has moved forwarded
225+
) {
226+
this.logService.trace('Settings Sync: Merging remote contents with settings file.');
227+
const { settingsPreview, hasChanges, hasConflicts } = this.mergeContents(localContent, remoteContent, lastSyncData ? lastSyncData.content : null);
228+
if (hasChanges) {
229+
// Sync only if there are changes
230+
hasLocalChanged = settingsPreview !== localContent; // Local has changed
231+
hasRemoteChanged = settingsPreview !== remoteContent; // Remote has changed
254232
return { settingsPreview, hasLocalChanged, hasRemoteChanged, hasConflicts };
255233
}
256-
257-
// New local contents. Sync with Local.
258-
this.logService.trace('Settings Sync: Remote contents have not changed. Settings file has changed. So sync with settings file.');
259-
hasRemoteChanged = true;
260-
settingsPreview = localContent;
261-
return { settingsPreview, hasLocalChanged, hasRemoteChanged, hasConflicts };
262234
}
263-
264235
}
265236

237+
this.logService.trace('Settings Sync: No changes.');
266238
return { settingsPreview, hasLocalChanged, hasRemoteChanged, hasConflicts };
267239

268240
}
269241

270-
private mergeContents(localContent: string, remoteContent: string, lastSyncedContent: string | null): { settingsPreview: string, hasConflicts: boolean } {
242+
private mergeContents(localContent: string, remoteContent: string, lastSyncedContent: string | null): { settingsPreview: string, hasChanges: boolean; hasConflicts: boolean } {
271243
const local = parse(localContent);
272244
const remote = parse(remoteContent);
273-
const base = lastSyncedContent ? parse(lastSyncedContent) : null;
274-
const settingsPreviewModel = this.modelService.createModel(localContent, this.modeService.create('jsonc'));
245+
const localToRemote = this.compare(local, remote);
275246

247+
if (localToRemote.added.size === 0 && localToRemote.removed.size === 0 && localToRemote.updated.size === 0) {
248+
// No changes found between local and remote.
249+
return { settingsPreview: localContent, hasChanges: false, hasConflicts: false };
250+
}
251+
252+
const settingsPreviewModel = this.modelService.createModel(localContent, this.modeService.create('jsonc'));
253+
const base = lastSyncedContent ? parse(lastSyncedContent) : null;
276254
const baseToLocal = base ? this.compare(base, local) : { added: Object.keys(local).reduce((r, k) => { r.add(k); return r; }, new Set<string>()), removed: new Set<string>(), updated: new Set<string>() };
277255
const baseToRemote = base ? this.compare(base, remote) : { added: Object.keys(remote).reduce((r, k) => { r.add(k); return r; }, new Set<string>()), removed: new Set<string>(), updated: new Set<string>() };
278-
const localToRemote = this.compare(local, remote);
279256

280257
const conflicts: Set<string> = new Set<string>();
281258

@@ -384,7 +361,7 @@ export class SettingsSynchroniser extends Disposable implements ISynchroniser {
384361
}
385362
}
386363

387-
return { settingsPreview: settingsPreviewModel.getValue(), hasConflicts: conflicts.size > 0 };
364+
return { settingsPreview: settingsPreviewModel.getValue(), hasChanges: true, hasConflicts: conflicts.size > 0 };
388365
}
389366

390367
private compare(from: { [key: string]: any }, to: { [key: string]: any }): { added: Set<string>, removed: Set<string>, updated: Set<string> } {

0 commit comments

Comments
 (0)