mirror of
https://github.com/Microsoft/vscode
synced 2024-10-02 17:32:41 +00:00
Git - only show "Incoming changes" node for upstream (#202836)
* Git - only show "Incoming changes" node for upstream * 💄 Revert some of the changes now that base is limited to upstream * Fixed a bug * 💄 More clean-up
This commit is contained in:
parent
600e284b84
commit
945bbd01aa
|
@ -12,14 +12,6 @@ import { Branch, RefType, UpstreamRef } from './api/git';
|
|||
import { emojify, ensureEmojis } from './emoji';
|
||||
import { Operation } from './operation';
|
||||
|
||||
function isBranchRefEqual(brach1: Branch | undefined, branch2: Branch | undefined): boolean {
|
||||
return brach1?.name === branch2?.name && brach1?.commit === branch2?.commit;
|
||||
}
|
||||
|
||||
function isUpstreamRefEqual(upstream1: UpstreamRef | undefined, upstream2: UpstreamRef | undefined): boolean {
|
||||
return upstream1?.name === upstream2?.name && upstream1?.remote === upstream2?.remote && upstream1?.commit === upstream2?.commit;
|
||||
}
|
||||
|
||||
export class GitHistoryProvider implements SourceControlHistoryProvider, FileDecorationProvider, IDisposable {
|
||||
|
||||
private readonly _onDidChangeCurrentHistoryItemGroup = new EventEmitter<void>();
|
||||
|
@ -29,15 +21,10 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
readonly onDidChangeFileDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
|
||||
|
||||
private _HEAD: Branch | undefined;
|
||||
private _HEADBase: UpstreamRef | undefined;
|
||||
private _currentHistoryItemGroup: SourceControlHistoryItemGroup | undefined;
|
||||
|
||||
get currentHistoryItemGroup(): SourceControlHistoryItemGroup | undefined { return this._currentHistoryItemGroup; }
|
||||
set currentHistoryItemGroup(value: SourceControlHistoryItemGroup | undefined) {
|
||||
if (this._currentHistoryItemGroup === undefined && value === undefined) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._currentHistoryItemGroup = value;
|
||||
this._onDidChangeCurrentHistoryItemGroup.fire();
|
||||
}
|
||||
|
@ -54,31 +41,30 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
}
|
||||
|
||||
private async onDidRunGitStatus(): Promise<void> {
|
||||
// Check if HEAD does not support incoming/outgoing (detached commit, tag)
|
||||
if (!this.repository.HEAD?.name || !this.repository.HEAD?.commit || this.repository.HEAD.type === RefType.Tag) {
|
||||
this._HEAD = this._HEADBase = undefined;
|
||||
this.currentHistoryItemGroup = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
// Resolve HEAD base
|
||||
const HEADBase = await this.resolveHEADBase(this.repository.HEAD);
|
||||
|
||||
// Check if HEAD or HEADBase has changed
|
||||
if (isBranchRefEqual(this._HEAD, this.repository.HEAD) && isUpstreamRefEqual(this._HEADBase, HEADBase)) {
|
||||
// Check if HEAD has changed
|
||||
if (this._HEAD?.name === this.repository.HEAD?.name &&
|
||||
this._HEAD?.commit === this.repository.HEAD?.commit &&
|
||||
this._HEAD?.upstream?.name === this.repository.HEAD?.upstream?.name &&
|
||||
this._HEAD?.upstream?.remote === this.repository.HEAD?.upstream?.remote &&
|
||||
this._HEAD?.upstream?.commit === this.repository.HEAD?.upstream?.commit) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._HEAD = this.repository.HEAD;
|
||||
this._HEADBase = HEADBase;
|
||||
|
||||
// Check if HEAD does not support incoming/outgoing (detached commit, tag)
|
||||
if (!this._HEAD?.name || !this._HEAD?.commit || this._HEAD.type === RefType.Tag) {
|
||||
this.currentHistoryItemGroup = undefined;
|
||||
return;
|
||||
}
|
||||
|
||||
this.currentHistoryItemGroup = {
|
||||
id: `refs/heads/${this._HEAD.name ?? ''}`,
|
||||
label: this._HEAD.name ?? '',
|
||||
base: this._HEADBase ?
|
||||
base: this._HEAD.upstream ?
|
||||
{
|
||||
id: `refs/remotes/${this._HEADBase.remote}/${this._HEADBase.name}`,
|
||||
label: `${this._HEADBase.remote}/${this._HEADBase.name}`,
|
||||
id: `refs/remotes/${this._HEAD.upstream.remote}/${this._HEAD.upstream.name}`,
|
||||
label: `${this._HEAD.upstream.remote}/${this._HEAD.upstream.name}`,
|
||||
} : undefined
|
||||
};
|
||||
}
|
||||
|
@ -165,17 +151,26 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
return historyItemChanges;
|
||||
}
|
||||
|
||||
async resolveHistoryItemGroupCommonAncestor(refId1: string, refId2: string): Promise<{ id: string; ahead: number; behind: number } | undefined> {
|
||||
const ancestor = await this.repository.getMergeBase(refId1, refId2);
|
||||
async resolveHistoryItemGroupCommonAncestor(historyItemId1: string, historyItemId2: string | undefined): Promise<{ id: string; ahead: number; behind: number } | undefined> {
|
||||
if (!historyItemId2) {
|
||||
const upstreamRef = await this.resolveHistoryItemGroupBase(historyItemId1);
|
||||
if (!upstreamRef) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
historyItemId2 = `refs/remotes/${upstreamRef.remote}/${upstreamRef.name}`;
|
||||
}
|
||||
|
||||
const ancestor = await this.repository.getMergeBase(historyItemId1, historyItemId2);
|
||||
if (!ancestor) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
try {
|
||||
const commitCount = await this.repository.getCommitCount(`${refId1}...${refId2}`);
|
||||
const commitCount = await this.repository.getCommitCount(`${historyItemId1}...${historyItemId2}`);
|
||||
return { id: ancestor, ahead: commitCount.ahead, behind: commitCount.behind };
|
||||
} catch (err) {
|
||||
this.logger.error(`Failed to get ahead/behind for '${refId1}...${refId2}': ${err.message}`);
|
||||
this.logger.error(`Failed to get ahead/behind for '${historyItemId1}...${historyItemId2}': ${err.message}`);
|
||||
}
|
||||
|
||||
return undefined;
|
||||
|
@ -185,27 +180,22 @@ export class GitHistoryProvider implements SourceControlHistoryProvider, FileDec
|
|||
return this.historyItemDecorations.get(uri.toString());
|
||||
}
|
||||
|
||||
private async resolveHEADBase(HEAD: Branch): Promise<UpstreamRef | undefined> {
|
||||
// Upstream
|
||||
if (HEAD.upstream) {
|
||||
return HEAD.upstream;
|
||||
private async resolveHistoryItemGroupBase(historyItemId: string): Promise<UpstreamRef | undefined> {
|
||||
try {
|
||||
const remoteBranch = await this.repository.getBranchBase(historyItemId);
|
||||
if (!remoteBranch?.remote || !remoteBranch?.name || !remoteBranch?.commit || remoteBranch?.type !== RefType.RemoteHead) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return {
|
||||
name: remoteBranch.name,
|
||||
remote: remoteBranch.remote,
|
||||
commit: remoteBranch.commit
|
||||
};
|
||||
}
|
||||
catch (err) {
|
||||
this.logger.error(`Failed to get branch base for '${historyItemId}': ${err.message}`);
|
||||
}
|
||||
|
||||
// try {
|
||||
// const remoteBranch = await this.repository.getBranchBase(HEAD.name ?? '');
|
||||
// if (!remoteBranch?.remote || !remoteBranch?.name || !remoteBranch?.commit || remoteBranch?.type !== RefType.RemoteHead) {
|
||||
// return undefined;
|
||||
// }
|
||||
|
||||
// return {
|
||||
// name: remoteBranch.name,
|
||||
// remote: remoteBranch.remote,
|
||||
// commit: remoteBranch.commit
|
||||
// };
|
||||
// }
|
||||
// catch (err) {
|
||||
// this.logger.error(`Failed to get branch base for '${HEAD.name}': ${err.message}`);
|
||||
// }
|
||||
|
||||
return undefined;
|
||||
}
|
||||
|
|
|
@ -140,7 +140,7 @@ class MainThreadSCMHistoryProvider implements ISCMHistoryProvider {
|
|||
|
||||
constructor(private readonly proxy: ExtHostSCMShape, private readonly handle: number) { }
|
||||
|
||||
async resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string): Promise<{ id: string; ahead: number; behind: number } | undefined> {
|
||||
async resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string | undefined): Promise<{ id: string; ahead: number; behind: number } | undefined> {
|
||||
return this.proxy.$resolveHistoryItemGroupCommonAncestor(this.handle, historyItemGroupId1, historyItemGroupId2, CancellationToken.None);
|
||||
}
|
||||
|
||||
|
|
|
@ -2239,7 +2239,7 @@ export interface ExtHostSCMShape {
|
|||
$provideHistoryItems(sourceControlHandle: number, historyItemGroupId: string, options: any, token: CancellationToken): Promise<SCMHistoryItemDto[] | undefined>;
|
||||
$provideHistoryItemSummary(sourceControlHandle: number, historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): Promise<SCMHistoryItemDto | undefined>;
|
||||
$provideHistoryItemChanges(sourceControlHandle: number, historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): Promise<SCMHistoryItemChangeDto[] | undefined>;
|
||||
$resolveHistoryItemGroupCommonAncestor(sourceControlHandle: number, historyItemGroupId1: string, historyItemGroupId2: string, token: CancellationToken): Promise<{ id: string; ahead: number; behind: number } | undefined>;
|
||||
$resolveHistoryItemGroupCommonAncestor(sourceControlHandle: number, historyItemGroupId1: string, historyItemGroupId2: string | undefined, token: CancellationToken): Promise<{ id: string; ahead: number; behind: number } | undefined>;
|
||||
}
|
||||
|
||||
export interface ExtHostQuickDiffShape {
|
||||
|
|
|
@ -960,7 +960,7 @@ export class ExtHostSCM implements ExtHostSCMShape {
|
|||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
async $resolveHistoryItemGroupCommonAncestor(sourceControlHandle: number, historyItemGroupId1: string, historyItemGroupId2: string, token: CancellationToken): Promise<{ id: string; ahead: number; behind: number } | undefined> {
|
||||
async $resolveHistoryItemGroupCommonAncestor(sourceControlHandle: number, historyItemGroupId1: string, historyItemGroupId2: string | undefined, token: CancellationToken): Promise<{ id: string; ahead: number; behind: number } | undefined> {
|
||||
const historyProvider = this._sourceControls.get(sourceControlHandle)?.historyProvider;
|
||||
return await historyProvider?.resolveHistoryItemGroupCommonAncestor(historyItemGroupId1, historyItemGroupId2, token) ?? undefined;
|
||||
}
|
||||
|
|
|
@ -3291,7 +3291,7 @@ class SCMTreeDataSource implements IAsyncDataSource<ISCMViewService, TreeElement
|
|||
}
|
||||
|
||||
async getChildren(inputOrElement: ISCMViewService | TreeElement): Promise<Iterable<TreeElement>> {
|
||||
const { alwaysShowRepositories, showActionButton, showIncomingChanges, showOutgoingChanges } = this.getConfiguration();
|
||||
const { alwaysShowRepositories, showActionButton } = this.getConfiguration();
|
||||
const repositoryCount = this.scmViewService.visibleRepositories.length;
|
||||
|
||||
if (isSCMViewService(inputOrElement) && (repositoryCount > 1 || alwaysShowRepositories)) {
|
||||
|
@ -3331,10 +3331,13 @@ class SCMTreeDataSource implements IAsyncDataSource<ISCMViewService, TreeElement
|
|||
let label = localize('syncSeparatorHeader', "Incoming/Outgoing");
|
||||
let ariaLabel = localize('syncSeparatorHeaderAriaLabel', "Incoming and outgoing changes");
|
||||
|
||||
if (showIncomingChanges !== 'never' && showOutgoingChanges === 'never') {
|
||||
const incomingHistoryItems = historyItemGroups.find(g => g.direction === 'incoming');
|
||||
const outgoingHistoryItems = historyItemGroups.find(g => g.direction === 'outgoing');
|
||||
|
||||
if (incomingHistoryItems && !outgoingHistoryItems) {
|
||||
label = localize('syncIncomingSeparatorHeader', "Incoming");
|
||||
ariaLabel = localize('syncIncomingSeparatorHeaderAriaLabel', "Incoming changes");
|
||||
} else if (showIncomingChanges === 'never' && showOutgoingChanges !== 'never') {
|
||||
} else if (!incomingHistoryItems && outgoingHistoryItems) {
|
||||
label = localize('syncOutgoingSeparatorHeader', "Outgoing");
|
||||
ariaLabel = localize('syncOutgoingSeparatorHeaderAriaLabel', "Outgoing changes");
|
||||
}
|
||||
|
@ -3384,7 +3387,7 @@ class SCMTreeDataSource implements IAsyncDataSource<ISCMViewService, TreeElement
|
|||
const historyProvider = scmProvider.historyProvider;
|
||||
const currentHistoryItemGroup = historyProvider?.currentHistoryItemGroup;
|
||||
|
||||
if (!historyProvider || !currentHistoryItemGroup || !currentHistoryItemGroup.base || (showIncomingChanges === 'never' && showOutgoingChanges === 'never')) {
|
||||
if (!historyProvider || !currentHistoryItemGroup || (showIncomingChanges === 'never' && showOutgoingChanges === 'never')) {
|
||||
return [];
|
||||
}
|
||||
|
||||
|
@ -3396,12 +3399,13 @@ class SCMTreeDataSource implements IAsyncDataSource<ISCMViewService, TreeElement
|
|||
|
||||
if (!incomingHistoryItemGroup || !outgoingHistoryItemGroup) {
|
||||
// Common ancestor, ahead, behind
|
||||
const ancestor = await historyProvider.resolveHistoryItemGroupCommonAncestor(currentHistoryItemGroup.id, currentHistoryItemGroup.base.id);
|
||||
const ancestor = await historyProvider.resolveHistoryItemGroupCommonAncestor(currentHistoryItemGroup.id, currentHistoryItemGroup.base?.id);
|
||||
if (!ancestor) {
|
||||
return [];
|
||||
}
|
||||
|
||||
incomingHistoryItemGroup = {
|
||||
// Only show "Incoming" node if there is a base branch
|
||||
incomingHistoryItemGroup = currentHistoryItemGroup.base ? {
|
||||
id: currentHistoryItemGroup.base.id,
|
||||
label: currentHistoryItemGroup.base.label,
|
||||
ariaLabel: localize('incomingChangesAriaLabel', "Incoming changes from {0}", currentHistoryItemGroup.base.label),
|
||||
|
@ -3411,7 +3415,7 @@ class SCMTreeDataSource implements IAsyncDataSource<ISCMViewService, TreeElement
|
|||
count: ancestor.behind,
|
||||
repository: element,
|
||||
type: 'historyItemGroup'
|
||||
};
|
||||
} : undefined;
|
||||
|
||||
outgoingHistoryItemGroup = {
|
||||
id: currentHistoryItemGroup.id,
|
||||
|
|
|
@ -26,7 +26,7 @@ export interface ISCMHistoryProvider {
|
|||
provideHistoryItems(historyItemGroupId: string, options: ISCMHistoryOptions): Promise<ISCMHistoryItem[] | undefined>;
|
||||
provideHistoryItemSummary(historyItemId: string, historyItemParentId: string | undefined): Promise<ISCMHistoryItem | undefined>;
|
||||
provideHistoryItemChanges(historyItemId: string, historyItemParentId: string | undefined): Promise<ISCMHistoryItemChange[] | undefined>;
|
||||
resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string): Promise<{ id: string; ahead: number; behind: number } | undefined>;
|
||||
resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string | undefined): Promise<{ id: string; ahead: number; behind: number } | undefined>;
|
||||
}
|
||||
|
||||
export interface ISCMHistoryProviderCacheEntry {
|
||||
|
|
|
@ -28,7 +28,7 @@ declare module 'vscode' {
|
|||
provideHistoryItemSummary?(historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): ProviderResult<SourceControlHistoryItem>;
|
||||
provideHistoryItemChanges(historyItemId: string, historyItemParentId: string | undefined, token: CancellationToken): ProviderResult<SourceControlHistoryItemChange[]>;
|
||||
|
||||
resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string, token: CancellationToken): ProviderResult<{ id: string; ahead: number; behind: number }>;
|
||||
resolveHistoryItemGroupCommonAncestor(historyItemGroupId1: string, historyItemGroupId2: string | undefined, token: CancellationToken): ProviderResult<{ id: string; ahead: number; behind: number }>;
|
||||
}
|
||||
|
||||
export interface SourceControlHistoryOptions {
|
||||
|
|
Loading…
Reference in a new issue