diff --git a/extensions/git/src/historyProvider.ts b/extensions/git/src/historyProvider.ts index bf083f723fb..cb94816874f 100644 --- a/extensions/git/src/historyProvider.ts +++ b/extensions/git/src/historyProvider.ts @@ -83,13 +83,16 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec this.currentHistoryItemGroup = { id: `refs/heads/${this.repository.HEAD.name ?? ''}`, name: this.repository.HEAD.name ?? '', + revision: this.repository.HEAD.commit ?? '', remote: this.repository.HEAD.upstream ? { id: `refs/remotes/${this.repository.HEAD.upstream.remote}/${this.repository.HEAD.upstream.name}`, name: `${this.repository.HEAD.upstream.remote}/${this.repository.HEAD.upstream.name}`, + revision: this.repository.HEAD.upstream.commit ?? '' } : undefined, base: mergeBase ? { id: `refs/remotes/${mergeBase.remote}/${mergeBase.name}`, name: `${mergeBase.remote}/${mergeBase.name}`, + revision: mergeBase.commit ?? '' } : undefined }; diff --git a/src/vs/workbench/api/browser/mainThreadSCM.ts b/src/vs/workbench/api/browser/mainThreadSCM.ts index 1311f30eb71..d35131056be 100644 --- a/src/vs/workbench/api/browser/mainThreadSCM.ts +++ b/src/vs/workbench/api/browser/mainThreadSCM.ts @@ -6,7 +6,7 @@ import { Barrier } from 'vs/base/common/async'; import { URI, UriComponents } from 'vs/base/common/uri'; import { Event, Emitter } from 'vs/base/common/event'; -import { observableValue } from 'vs/base/common/observable'; +import { derivedOpts, observableValue, observableValueOpts } from 'vs/base/common/observable'; import { IDisposable, DisposableStore, combinedDisposable, dispose, Disposable } from 'vs/base/common/lifecycle'; import { ISCMService, ISCMRepository, ISCMProvider, ISCMResource, ISCMResourceGroup, ISCMResourceDecorations, IInputValidation, ISCMViewService, InputValidationType, ISCMActionButtonDescriptor } from 'vs/workbench/contrib/scm/common/scm'; import { ExtHostContext, MainThreadSCMShape, ExtHostSCMShape, SCMProviderFeatures, SCMRawResourceSplices, SCMGroupFeatures, MainContext, SCMHistoryItemGroupDto, SCMHistoryItemDto } from '../common/extHost.protocol'; @@ -17,7 +17,7 @@ import { MarshalledId } from 'vs/base/common/marshallingIds'; import { ThemeIcon } from 'vs/base/common/themables'; import { IMarkdownString } from 'vs/base/common/htmlContent'; import { IQuickDiffService, QuickDiffProvider } from 'vs/workbench/contrib/scm/common/quickDiff'; -import { ISCMHistoryItem, ISCMHistoryItemChange, ISCMHistoryItemGroup, ISCMHistoryOptions, ISCMHistoryProvider } from 'vs/workbench/contrib/scm/common/history'; +import { ISCMHistoryItem, ISCMHistoryItemChange, ISCMHistoryItemGroup, ISCMHistoryItemGroupWithRevision, ISCMHistoryOptions, ISCMHistoryProvider } from 'vs/workbench/contrib/scm/common/history'; import { ResourceTree } from 'vs/base/common/resourceTree'; import { IUriIdentityService } from 'vs/platform/uriIdentity/common/uriIdentity'; import { IWorkspaceContextService } from 'vs/platform/workspace/common/workspace'; @@ -27,6 +27,7 @@ import { IModelService } from 'vs/editor/common/services/model'; import { ITextModelContentProvider, ITextModelService } from 'vs/editor/common/services/resolverService'; import { Schemas } from 'vs/base/common/network'; import { ITextModel } from 'vs/editor/common/model'; +import { structuralEquals } from 'vs/base/common/equals'; function getIconFromIconDto(iconDto?: UriComponents | { light: UriComponents; dark: UriComponents } | ThemeIcon): URI | { light: URI; dark: URI } | ThemeIcon | undefined { if (iconDto === undefined) { @@ -48,6 +49,12 @@ function toISCMHistoryItem(historyItemDto: SCMHistoryItemDto): ISCMHistoryItem { return { ...historyItemDto, icon, labels }; } +function historyItemGroupEquals(a: ISCMHistoryItemGroup | undefined, b: ISCMHistoryItemGroup | undefined): boolean { + return a?.id === b?.id && a?.name === b?.name && + a?.base?.id === b?.base?.id && a?.base?.name === b?.base?.name && + a?.remote?.id === b?.remote?.id && a?.remote?.name === b?.remote?.name; +} + class SCMInputBoxContentProvider extends Disposable implements ITextModelContentProvider { constructor( textModelService: ITextModelService, @@ -164,16 +171,27 @@ class MainThreadSCMHistoryProvider implements ISCMHistoryProvider { private _onDidChangeCurrentHistoryItemGroup = new Emitter(); readonly onDidChangeCurrentHistoryItemGroup = this._onDidChangeCurrentHistoryItemGroup.event; - private _currentHistoryItemGroup: ISCMHistoryItemGroup | undefined; - get currentHistoryItemGroup(): ISCMHistoryItemGroup | undefined { return this._currentHistoryItemGroup; } - set currentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroup | undefined) { + private _currentHistoryItemGroup: ISCMHistoryItemGroupWithRevision | undefined; + get currentHistoryItemGroup(): ISCMHistoryItemGroupWithRevision | undefined { return this._currentHistoryItemGroup; } + set currentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroupWithRevision | undefined) { this._currentHistoryItemGroup = historyItemGroup; this._onDidChangeCurrentHistoryItemGroup.fire(); } - private readonly _currentHistoryItemGroupObs = observableValue(this, undefined); + /** + * Changes when the id/name changes for the current, remote, or base history item group + */ + private readonly _currentHistoryItemGroupObs = derivedOpts({ + owner: this, equalsFn: historyItemGroupEquals, + }, reader => this._currentHistoryItemGroupWithRevisionObs.read(reader)); get currentHistoryItemGroupObs() { return this._currentHistoryItemGroupObs; } + /** + * Changes when the id/name/revision changes for the current, remote, or base history item group + */ + private readonly _currentHistoryItemGroupWithRevisionObs = observableValueOpts({ owner: this, equalsFn: structuralEquals }, undefined); + get currentHistoryItemGroupWithRevisionObs() { return this._currentHistoryItemGroupWithRevisionObs; } + constructor(private readonly proxy: ExtHostSCMShape, private readonly handle: number) { } async resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string | undefined): Promise<{ id: string; ahead: number; behind: number } | undefined> { @@ -209,8 +227,8 @@ class MainThreadSCMHistoryProvider implements ISCMHistoryProvider { })); } - $onDidChangeCurrentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroup | undefined): void { - this._currentHistoryItemGroupObs.set(historyItemGroup, undefined); + $onDidChangeCurrentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroupWithRevision | undefined): void { + this._currentHistoryItemGroupWithRevisionObs.set(historyItemGroup, undefined); } } diff --git a/src/vs/workbench/api/common/extHost.protocol.ts b/src/vs/workbench/api/common/extHost.protocol.ts index ae3c9f43ea7..70cd8cb371a 100644 --- a/src/vs/workbench/api/common/extHost.protocol.ts +++ b/src/vs/workbench/api/common/extHost.protocol.ts @@ -1516,6 +1516,7 @@ export type SCMRawResourceSplices = [ export interface SCMHistoryItemGroupDto { readonly id: string; readonly name: string; + readonly revision: string; readonly base?: Omit, 'remote'>; readonly remote?: Omit, 'remote'>; } diff --git a/src/vs/workbench/contrib/scm/common/history.ts b/src/vs/workbench/contrib/scm/common/history.ts index e0e1e1084c4..f708d8617b8 100644 --- a/src/vs/workbench/contrib/scm/common/history.ts +++ b/src/vs/workbench/contrib/scm/common/history.ts @@ -21,9 +21,10 @@ export interface ISCMHistoryProvider { readonly onDidChangeCurrentHistoryItemGroup: Event; - get currentHistoryItemGroup(): ISCMHistoryItemGroup | undefined; - set currentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroup | undefined); + get currentHistoryItemGroup(): ISCMHistoryItemGroupWithRevision | undefined; + set currentHistoryItemGroup(historyItemGroup: ISCMHistoryItemGroupWithRevision | undefined); readonly currentHistoryItemGroupObs: IObservable; + readonly currentHistoryItemGroupWithRevisionObs: IObservable; provideHistoryItems(historyItemGroupId: string, options: ISCMHistoryOptions): Promise; provideHistoryItems2(options: ISCMHistoryOptions): Promise; @@ -54,6 +55,14 @@ export interface ISCMHistoryItemGroup { readonly remote?: Omit, 'remote'>; } +export interface ISCMHistoryItemGroupWithRevision { + readonly id: string; + readonly name: string; + readonly revision: string; + readonly base?: Omit, 'remote'>; + readonly remote?: Omit, 'remote'>; +} + export interface SCMHistoryItemGroupTreeElement { readonly id: string; readonly label: string; diff --git a/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts b/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts index ee0fdcb8572..f79fa1885b9 100644 --- a/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.scmHistoryProvider.d.ts @@ -42,6 +42,7 @@ declare module 'vscode' { export interface SourceControlHistoryItemGroup { readonly id: string; readonly name: string; + readonly revision: string; readonly base?: Omit, 'remote'>; readonly remote?: Omit, 'remote'>; }