diff --git a/extensions/git/src/historyProvider.ts b/extensions/git/src/historyProvider.ts index a6e97c63763..9e8dfc2bc7e 100644 --- a/extensions/git/src/historyProvider.ts +++ b/extensions/git/src/historyProvider.ts @@ -78,12 +78,12 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec throw new Error('Unsupported options.'); } - const optionsRef = options.limit.id; - const historyItemGroupIdRef = await this.repository.revParse(historyItemGroupId) ?? ''; + const refParentId = options.limit.id; + const refId = await this.repository.revParse(historyItemGroupId) ?? ''; - const [commits, summary] = await Promise.all([ - this.repository.log({ range: `${optionsRef}..${historyItemGroupIdRef}`, shortStats: true, sortByAuthorDate: true }), - this.getSummaryHistoryItem(optionsRef, historyItemGroupIdRef) + const [summary, commits] = await Promise.all([ + this.getSummaryHistoryItem(refId, refParentId), + this.repository.log({ range: `${refParentId}..${refId}`, shortStats: true, sortByAuthorDate: true }) ]); await ensureEmojis(); @@ -107,20 +107,15 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec return historyItems; } - async provideHistoryItemChanges(historyItemId: string): Promise { - // The "All Changes" history item uses a special id - // which is a commit range instead of a single commit id - let [originalRef, modifiedRef] = historyItemId.includes('..') - ? historyItemId.split('..') : [undefined, historyItemId]; - - if (!originalRef) { - const commit = await this.repository.getCommit(modifiedRef); - originalRef = commit.parents.length > 0 ? commit.parents[0] : `${modifiedRef}^`; + async provideHistoryItemChanges(historyItemId: string, historyItemParentId: string | undefined): Promise { + if (!historyItemParentId) { + const commit = await this.repository.getCommit(historyItemId); + historyItemParentId = commit.parents.length > 0 ? commit.parents[0] : `${historyItemId}^`; } const historyItemChangesUri: Uri[] = []; const historyItemChanges: SourceControlHistoryItemChange[] = []; - const changes = await this.repository.diffBetween(originalRef, modifiedRef); + const changes = await this.repository.diffBetween(historyItemParentId, historyItemId); for (const change of changes) { const historyItemUri = change.uri.with({ @@ -130,8 +125,8 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec // History item change historyItemChanges.push({ uri: historyItemUri, - originalUri: toGitUri(change.originalUri, originalRef), - modifiedUri: toGitUri(change.originalUri, modifiedRef), + originalUri: toGitUri(change.originalUri, historyItemParentId), + modifiedUri: toGitUri(change.originalUri, historyItemId), renameUri: change.renameUri, }); @@ -208,9 +203,9 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec return new FileDecoration(letter, tooltip, color); } - private async getSummaryHistoryItem(ref1: string, ref2: string): Promise { - const statistics = await this.repository.diffBetweenShortStat(ref1, ref2); - return { id: `${ref1}..${ref2}`, parentIds: [], icon: new ThemeIcon('files'), label: l10n.t('All Changes'), statistics }; + private async getSummaryHistoryItem(refId: string, refParentId: string): Promise { + const statistics = await this.repository.diffBetweenShortStat(refParentId, refId); + return { id: refId, parentIds: [refParentId], icon: new ThemeIcon('files'), label: l10n.t('All Changes'), statistics }; } dispose(): void { diff --git a/src/vs/workbench/api/browser/mainThreadSCM.ts b/src/vs/workbench/api/browser/mainThreadSCM.ts index 345a52efcdf..f42a0b5d9f4 100644 --- a/src/vs/workbench/api/browser/mainThreadSCM.ts +++ b/src/vs/workbench/api/browser/mainThreadSCM.ts @@ -187,8 +187,8 @@ class MainThreadSCMHistoryProvider implements ISCMHistoryProvider { return historyItems?.map(historyItem => ({ ...historyItem, icon: getIconFromIconDto(historyItem.icon) })); } - async provideHistoryItemChanges(historyItemId: string): Promise { - const changes = await this.proxy.$provideHistoryItemChanges(this.handle, historyItemId, CancellationToken.None); + async provideHistoryItemChanges(historyItemId: string, historyItemParentId: string | undefined): Promise { + const changes = await this.proxy.$provideHistoryItemChanges(this.handle, historyItemId, historyItemParentId, CancellationToken.None); return changes?.map(change => ({ uri: URI.revive(change.uri), originalUri: change.originalUri && URI.revive(change.originalUri), diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index 712156eff9e..c6dbe8b3a75 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -2220,7 +2220,7 @@ export interface ExtHostSCMShape { $validateInput(sourceControlHandle: number, value: string, cursorPosition: number): Promise<[string | IMarkdownString, number] | undefined>; $setSelectedSourceControl(selectedSourceControlHandle: number | undefined): Promise; $provideHistoryItems(sourceControlHandle: number, historyItemGroupId: string, options: any, token: CancellationToken): Promise; - $provideHistoryItemChanges(sourceControlHandle: number, historyItemId: string, token: CancellationToken): Promise; + $provideHistoryItemChanges(sourceControlHandle: number, historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): Promise; $resolveHistoryItemGroupBase(sourceControlHandle: number, historyItemGroupId: string, token: CancellationToken): Promise; $resolveHistoryItemGroupCommonAncestor(sourceControlHandle: number, historyItemGroupId1: string, historyItemGroupId2: string, token: CancellationToken): Promise<{ id: string; ahead: number; behind: number } | undefined>; } diff --git a/src/vs/workbench/api/common/extHostSCM.ts b/src/vs/workbench/api/common/extHostSCM.ts index 74372613449..2c7d375a7a7 100644 --- a/src/vs/workbench/api/common/extHostSCM.ts +++ b/src/vs/workbench/api/common/extHostSCM.ts @@ -955,8 +955,8 @@ export class ExtHostSCM implements ExtHostSCMShape { return historyItems?.map(item => ({ ...item, icon: getHistoryItemIconDto(item) })) ?? undefined; } - async $provideHistoryItemChanges(sourceControlHandle: number, historyItemId: string, token: CancellationToken): Promise { + async $provideHistoryItemChanges(sourceControlHandle: number, historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): Promise { const historyProvider = this._sourceControls.get(sourceControlHandle)?.historyProvider; - return await historyProvider?.provideHistoryItemChanges(historyItemId, token) ?? undefined; + return await historyProvider?.provideHistoryItemChanges(historyItemId, historyItemParentId, token) ?? undefined; } } diff --git a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts index 75d5748e909..f2bd08bc1b6 100644 --- a/src/vs/workbench/contrib/scm/browser/scmViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmViewPane.ts @@ -1257,7 +1257,7 @@ function getSCMResourceId(element: TreeElement): string { } else if (isSCMHistoryItemTreeElement(element)) { const historyItemGroup = element.historyItemGroup; const provider = historyItemGroup.repository.provider; - return `historyItem:${provider.id}/${historyItemGroup.id}/${element.id}`; + return `historyItem:${provider.id}/${historyItemGroup.id}/${element.id}/${element.parentIds.join(',')}`; } else if (isSCMHistoryItemChangeTreeElement(element)) { const historyItem = element.historyItem; const historyItemGroup = historyItem.historyItemGroup; @@ -1713,7 +1713,8 @@ class HistoryItemViewChangesAction extends Action2 { return; } - const historyItemChanges = await historyProvider.provideHistoryItemChanges(historyItem.id); + const historyItemParentId = historyItem.parentIds.length > 0 ? historyItem.parentIds[0] : undefined; + const historyItemChanges = await historyProvider.provideHistoryItemChanges(historyItem.id, historyItemParentId); if (!historyItemChanges || historyItemChanges.length === 0) { return; } @@ -3417,13 +3418,17 @@ class SCMTreeDataSource implements IAsyncDataSource 0 ? element.parentIds[0] : undefined; + let historyItemChanges = historyItemChangesMap.get(`${element.id}/${historyItemParentId}`); if (!historyItemChanges) { - historyItemChanges = await historyProvider.provideHistoryItemChanges(element.id) ?? []; + const historyItemParentId = element.parentIds.length > 0 ? element.parentIds[0] : undefined; + historyItemChanges = await historyProvider.provideHistoryItemChanges(element.id, historyItemParentId) ?? []; + this.historyProviderCache.set(repository, { ...historyProviderCacheEntry, - historyItemChanges: historyItemChangesMap.set(element.id, historyItemChanges) + historyItemChanges: historyItemChangesMap.set(`${element.id}/${historyItemParentId}`, historyItemChanges) }); } diff --git a/src/vs/workbench/contrib/scm/common/history.ts b/src/vs/workbench/contrib/scm/common/history.ts index 5ccbce67e26..d1e61ec676c 100644 --- a/src/vs/workbench/contrib/scm/common/history.ts +++ b/src/vs/workbench/contrib/scm/common/history.ts @@ -21,7 +21,7 @@ export interface ISCMHistoryProvider { set currentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroup | undefined); provideHistoryItems(historyItemGroupId: string, options: ISCMHistoryOptions): Promise; - provideHistoryItemChanges(historyItemId: string): Promise; + provideHistoryItemChanges(historyItemId: string, historyItemParentId: string | undefined): Promise; resolveHistoryItemGroupBase(historyItemGroupId: string): Promise; resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string): Promise<{ id: string; ahead: number; behind: number } | undefined>; resolveHistoryItemGroupDetails(historyItemGroup: ISCMHistoryItemGroup): Promise; diff --git a/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts b/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts index 22ec4683f3b..8dd3dd899df 100644 --- a/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts @@ -25,7 +25,7 @@ declare module 'vscode' { // onDidChangeHistoryItemGroups: Event; provideHistoryItems(historyItemGroupId: string, options: SourceControlHistoryOptions, token: CancellationToken): ProviderResult; - provideHistoryItemChanges(historyItemId: string, token: CancellationToken): ProviderResult; + provideHistoryItemChanges(historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): ProviderResult; resolveHistoryItemGroupBase(historyItemGroupId: string, token: CancellationToken): ProviderResult; resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId: string, token: CancellationToken): ProviderResult<{ id: string; ahead: number; behind: number }>;