diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index e2d4eacb621..6a74dcaec2e 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -1174,6 +1174,9 @@ export class Repository { } if (options?.refNames) { + if (options.refNames.length === 0) { + args.push('--all'); + } args.push('--topo-order'); args.push('--decorate=full'); args.push(...options.refNames); diff --git a/src/vs/base/browser/markdownRenderer.ts b/src/vs/base/browser/markdownRenderer.ts index 447d5e02c3f..5a9c703ecd9 100644 --- a/src/vs/base/browser/markdownRenderer.ts +++ b/src/vs/base/browser/markdownRenderer.ts @@ -396,7 +396,7 @@ function sanitizeRenderedMarkdown( if (e.attrName === 'style' || e.attrName === 'class') { if (element.tagName === 'SPAN') { if (e.attrName === 'style') { - e.keepAttr = /^(color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z]+)+\));)?(background-color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z]+)+\));)?(border-radius:[0-9]+px;)?$/.test(e.attrValue); + e.keepAttr = /^(color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z0-9]+)+\));)?(background-color\:(#[0-9a-fA-F]+|var\(--vscode(-[a-zA-Z0-9]+)+\));)?(border-radius:[0-9]+px;)?$/.test(e.attrValue); return; } else if (e.attrName === 'class') { e.keepAttr = /^codicon codicon-[a-z\-]+( codicon-modifier-[a-z\-]+)?$/.test(e.attrValue); diff --git a/src/vs/workbench/contrib/scm/browser/scmHistory.ts b/src/vs/workbench/contrib/scm/browser/scmHistory.ts index 783b2daa830..c51e6fbcdd8 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistory.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistory.ts @@ -305,7 +305,20 @@ export function toISCMHistoryItemViewModelArray(historyItems: ISCMHistoryItem[], // Add colors to labels const labels = (historyItem.labels ?? []) .map(label => { - return { ...label, color: colorMap.get(label.title) }; + let color = colorMap.get(label.title); + if (!color && colorMap.has('*')) { + // Find the history item in the input swimlanes + const inputIndex = inputSwimlanes.findIndex(node => node.id === historyItem.id); + + // Circle index - use the input swimlane index if present, otherwise add it to the end + const circleIndex = inputIndex !== -1 ? inputIndex : inputSwimlanes.length; + + // Circle color - use the output swimlane color if present, otherwise the input swimlane color + color = circleIndex < outputSwimlanes.length ? outputSwimlanes[circleIndex].color : + circleIndex < inputSwimlanes.length ? inputSwimlanes[circleIndex].color : historyItemGroupLocal; + } + + return { ...label, color }; }); viewModels.push({ diff --git a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts index ef66cbdb272..51916fe9657 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts @@ -574,7 +574,33 @@ class SCMHistoryViewModel extends Disposable { * values are updated in the same transaction (or during the initial read of the observable value). */ readonly repository = latestChangedValue(this, [this._firstRepository, this._graphRepository]); - private readonly _historyItemGroupIds = observableValue<'all' | 'auto' | string[]>(this, 'auto'); + + private readonly _historyItemGroupFilter = observableValue<'all' | 'auto' | string[]>(this, 'auto'); + + readonly historyItemGroupFilter = derived(reader => { + const filter = this._historyItemGroupFilter.read(reader); + if (Array.isArray(filter)) { + return filter; + } + + if (filter === 'all') { + return []; + } + + const repository = this.repository.get(); + const historyProvider = repository?.provider.historyProvider.get(); + const currentHistoryItemGroup = historyProvider?.currentHistoryItemGroup.get(); + + if (!currentHistoryItemGroup) { + return []; + } + + return [ + currentHistoryItemGroup.revision ?? currentHistoryItemGroup.id, + ...currentHistoryItemGroup.remote ? [currentHistoryItemGroup.remote.revision ?? currentHistoryItemGroup.remote.id] : [], + ...currentHistoryItemGroup.base ? [currentHistoryItemGroup.base.revision ?? currentHistoryItemGroup.base.id] : [], + ]; + }); private readonly _state = new Map(); @@ -633,13 +659,9 @@ class SCMHistoryViewModel extends Disposable { } if (!state || state.loadMore) { - const historyItemGroupIds = [ - currentHistoryItemGroup.revision ?? currentHistoryItemGroup.id, - ...currentHistoryItemGroup.remote ? [currentHistoryItemGroup.remote.revision ?? currentHistoryItemGroup.remote.id] : [], - ...currentHistoryItemGroup.base ? [currentHistoryItemGroup.base.revision ?? currentHistoryItemGroup.base.id] : [], - ]; - const existingHistoryItems = state?.items ?? []; + + const historyItemGroupIds = this.historyItemGroupFilter.get(); const limit = clamp(this._configurationService.getValue('scm.graph.pageSize'), 1, 1000); const historyItems = await historyProvider.provideHistoryItems({ @@ -656,7 +678,7 @@ class SCMHistoryViewModel extends Disposable { } // Create the color map - const colorMap = this._getHistoryItemsColorMap(currentHistoryItemGroup); + const colorMap = this._getGraphColorMap(currentHistoryItemGroup); return toISCMHistoryItemViewModelArray(state.items, colorMap) .map(historyItemViewModel => ({ @@ -670,11 +692,7 @@ class SCMHistoryViewModel extends Disposable { this._selectedRepository.set(repository, undefined); } - private _getHistoryItemsColorMap(currentHistoryItemGroup: ISCMHistoryItemGroup): Map { - if (this._historyItemGroupIds.get() !== 'auto') { - return new Map(); - } - + private _getGraphColorMap(currentHistoryItemGroup: ISCMHistoryItemGroup): Map { const colorMap = new Map([ [currentHistoryItemGroup.name, historyItemGroupLocal] ]); @@ -684,6 +702,9 @@ class SCMHistoryViewModel extends Disposable { if (currentHistoryItemGroup.base) { colorMap.set(currentHistoryItemGroup.base.name, historyItemGroupBase); } + if (this._historyItemGroupFilter.get() === 'all') { + colorMap.set('*', ''); + } return colorMap; }