diff --git a/src/vs/platform/userDataSync/common/extensionsMerge.ts b/src/vs/platform/userDataSync/common/extensionsMerge.ts index 1202bbbba367e38a38531a626c087ef986db7569..96f79ba99e94e47b90f0777b515af97329f2ff49 100644 --- a/src/vs/platform/userDataSync/common/extensionsMerge.ts +++ b/src/vs/platform/userDataSync/common/extensionsMerge.ts @@ -74,10 +74,14 @@ export function merge(localExtensions: ISyncExtension[], remoteExtensions: ISync const baseToRemote = compare(lastSyncExtensionsMap, remoteExtensionsMap, ignoredExtensionsSet); const mergeAndUpdate = (key: string): void => { - const extension = remoteExtensionsMap.get(key)!; - extension.state = mergeExtensionState(localExtensionsMap.get(key)?.state, extension.state, lastSyncExtensionsMap?.get(key)?.state); - updated.push(massageOutgoingExtension(extension, key)); - newRemoteExtensionsMap.set(key, extension); + const localExtension = localExtensionsMap.get(key)!; + const remoteExtension = remoteExtensionsMap.get(key)!; + // merge extension state only when version matches and local extension has state + if (remoteExtension.version === localExtension.version && localExtension.state) { + remoteExtension.state = mergeExtensionState(localExtension.state, remoteExtension.state, lastSyncExtensionsMap?.get(key)?.state); + } + updated.push(massageOutgoingExtension(remoteExtension, key)); + newRemoteExtensionsMap.set(key, remoteExtension); }; // Remotely removed extension. @@ -183,18 +187,7 @@ function compare(from: Map | null, to: Map | undefined, remote: IStringDictionary | undefined, base: IStringDictionary | undefined): IStringDictionary | undefined { - if (!local && !remote && !base) { - return undefined; - } - if (local && !remote && !base) { - return local; - } - if (remote && !local && !base) { - return remote; - } - - local = local || {}; +function mergeExtensionState(local: IStringDictionary, remote: IStringDictionary | undefined, base: IStringDictionary | undefined): IStringDictionary | undefined { const merged: IStringDictionary = deepClone(local); if (remote) { const baseToRemote = base ? compareExtensionState(base, remote) : { added: Object.keys(remote).reduce((r, k) => { r.add(k); return r; }, new Set()), removed: new Set(), updated: new Set() }; diff --git a/src/vs/platform/userDataSync/common/extensionsSync.ts b/src/vs/platform/userDataSync/common/extensionsSync.ts index eb3a2825926e11ff95c2766249abf2aee204052c..df6dfb1fa4fb37ac70fc3d7bc385cd07b984c057 100644 --- a/src/vs/platform/userDataSync/common/extensionsSync.ts +++ b/src/vs/platform/userDataSync/common/extensionsSync.ts @@ -450,13 +450,13 @@ export class ExtensionsSynchroniser extends AbstractSynchroniser implements IUse syncExntesion.installed = true; } const keys = this.storageKeysSyncRegistryService.getExtensioStorageKeys({ id: identifier.id, version: manifest.version }); - try { - const extensionStorageValue = this.storageService.get(identifier.id, StorageScope.GLOBAL); - syncExntesion.state = keys.length && extensionStorageValue - ? JSON.parse(extensionStorageValue, (key, value) => !key || keys.includes(key) ? value : undefined) - : undefined; - } catch (error) { - this.logService.info(`${this.syncResourceLogLabel}: Error while parsing extension state`, getErrorMessage(error)); + if (keys) { + const extensionStorageValue = this.storageService.get(identifier.id, StorageScope.GLOBAL) || '{}'; + try { + syncExntesion.state = JSON.parse(extensionStorageValue, (key, value) => !key || keys.includes(key) ? value : undefined); + } catch (error) { + this.logService.info(`${this.syncResourceLogLabel}: Error while parsing extension state`, getErrorMessage(error)); + } } return syncExntesion; }); diff --git a/src/vs/platform/userDataSync/common/storageKeys.ts b/src/vs/platform/userDataSync/common/storageKeys.ts index 00d8a4d59d0856c158b3a8b80535ec67fa627b6c..5ffe0786f054e65fd3c9f74aba4c9d430495023f 100644 --- a/src/vs/platform/userDataSync/common/storageKeys.ts +++ b/src/vs/platform/userDataSync/common/storageKeys.ts @@ -76,7 +76,7 @@ export interface IStorageKeysSyncRegistryService { /** * Returns storage keys of the given extension that has to be synchronized. */ - getExtensioStorageKeys(extension: IExtensionIdWithVersion): ReadonlyArray; + getExtensioStorageKeys(extension: IExtensionIdWithVersion): ReadonlyArray | undefined; } export abstract class AbstractStorageKeysSyncRegistryService extends Disposable implements IStorageKeysSyncRegistryService { @@ -103,8 +103,8 @@ export abstract class AbstractStorageKeysSyncRegistryService extends Disposable this._register(toDisposable(() => this._storageKeys.clear())); } - getExtensioStorageKeys(extension: IExtensionIdWithVersion): ReadonlyArray { - return this._extensionsStorageKeys.get(ExtensionIdWithVersion.toKey(extension)) || []; + getExtensioStorageKeys(extension: IExtensionIdWithVersion): ReadonlyArray | undefined { + return this._extensionsStorageKeys.get(ExtensionIdWithVersion.toKey(extension)); } protected updateExtensionStorageKeys(extension: IExtensionIdWithVersion, keys: string[]): void { diff --git a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts index 94ace05dec671af3a002b02ed710b269f70825d6..a377564b02d59be22987e2061fb33c7c00357f3d 100644 --- a/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts +++ b/src/vs/workbench/electron-sandbox/sandbox.simpleservices.ts @@ -731,7 +731,7 @@ class SimpleIStorageKeysSyncRegistryService implements IStorageKeysSyncRegistryS extensionsStorageKeys = []; - getExtensioStorageKeys(): [] { return []; } + getExtensioStorageKeys() { return undefined; } registerExtensionStorageKeys(): void { } }