mirror of
https://github.com/microsoft/vscode.git
synced 2026-07-12 22:08:04 -05:00
SCM - add support for multi-select in the history graph (#222186)
This commit is contained in:
@@ -4192,17 +4192,33 @@ export class CommandCenter {
|
||||
}
|
||||
|
||||
@command('git.viewCommit', { repository: true })
|
||||
async viewCommit(repository: Repository, historyItem: SourceControlHistoryItem): Promise<void> {
|
||||
if (!repository || !historyItem) {
|
||||
async viewCommit(repository: Repository, historyItem1: SourceControlHistoryItem, historyItem2?: SourceControlHistoryItem): Promise<void> {
|
||||
if (!repository || !historyItem1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const commit = await repository.getCommit(historyItem.id);
|
||||
const title = `${historyItem.id.substring(0, 8)} - ${commit.message}`;
|
||||
if (historyItem2) {
|
||||
const mergeBase = await repository.getMergeBase(historyItem1.id, historyItem2.id);
|
||||
if (!mergeBase || (mergeBase !== historyItem1.id && mergeBase !== historyItem2.id)) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), historyItem.id, { scheme: 'git-commit' });
|
||||
const historyItemId = historyItem1.id;
|
||||
const historyItemParentId = historyItem2 ? historyItem2.id :
|
||||
historyItem1.parentIds.length > 0 ? historyItem1.parentIds[0] : `${historyItemId}^`;
|
||||
|
||||
await this._viewChanges(repository, historyItem, multiDiffSourceUri, title);
|
||||
let title = '';
|
||||
if (!historyItem2) {
|
||||
const commit = await repository.getCommit(historyItemId);
|
||||
title = `${historyItemId.substring(0, 8)} - ${commit.message}`;
|
||||
} else {
|
||||
title = l10n.t('All Changes ({0} ↔ {1})', historyItemParentId.substring(0, 8), historyItemId.substring(0, 8));
|
||||
}
|
||||
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), `${historyItemParentId}..${historyItemId}`, { scheme: 'git-commit', });
|
||||
|
||||
await this._viewChanges(repository, historyItemId, historyItemParentId, multiDiffSourceUri, title);
|
||||
}
|
||||
|
||||
@command('git.viewAllChanges', { repository: true })
|
||||
@@ -4217,18 +4233,17 @@ export class CommandCenter {
|
||||
|
||||
const multiDiffSourceUri = toGitUri(Uri.file(repository.root), historyItem.id, { scheme: 'git-changes' });
|
||||
|
||||
await this._viewChanges(repository, historyItem, multiDiffSourceUri, title);
|
||||
await this._viewChanges(repository, modifiedShortRef, originalShortRef, multiDiffSourceUri, title);
|
||||
}
|
||||
|
||||
async _viewChanges(repository: Repository, historyItem: SourceControlHistoryItem, multiDiffSourceUri: Uri, title: string): Promise<void> {
|
||||
const historyItemParentId = historyItem.parentIds.length > 0 ? historyItem.parentIds[0] : `${historyItem.id}^`;
|
||||
const changes = await repository.diffBetween(historyItemParentId, historyItem.id);
|
||||
async _viewChanges(repository: Repository, historyItemId: string, historyItemParentId: string, multiDiffSourceUri: Uri, title: string): Promise<void> {
|
||||
const changes = await repository.diffBetween(historyItemParentId, historyItemId);
|
||||
|
||||
if (changes.length === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
const resources = changes.map(c => toMultiFileDiffEditorUris(c, historyItemParentId, historyItem.id));
|
||||
const resources = changes.map(c => toMultiFileDiffEditorUris(c, historyItemParentId, historyItemId));
|
||||
|
||||
await commands.executeCommand('_workbench.openMultiDiffEditor', { multiDiffSourceUri, title, resources });
|
||||
}
|
||||
|
||||
@@ -822,28 +822,66 @@ class HistoryItemGroupRenderer implements ICompressibleTreeRenderer<SCMHistoryIt
|
||||
|
||||
class HistoryItemActionRunner extends ActionRunner {
|
||||
|
||||
protected override async runAction(action: IAction, context: SCMHistoryItemTreeElement | SCMHistoryItemViewModelTreeElement): Promise<any> {
|
||||
protected override async runAction(action: IAction, context: SCMHistoryItemTreeElement): Promise<any> {
|
||||
if (!(action instanceof MenuItemAction)) {
|
||||
return super.runAction(action, context);
|
||||
}
|
||||
|
||||
const args: (ISCMProvider | ISCMHistoryItem)[] = [];
|
||||
if (isSCMHistoryItemTreeElement(context)) {
|
||||
args.push(context.historyItemGroup.repository.provider);
|
||||
} else {
|
||||
args.push(context.repository.provider);
|
||||
args.push(context.historyItemGroup.repository.provider);
|
||||
|
||||
args.push({
|
||||
id: context.id,
|
||||
parentIds: context.parentIds,
|
||||
message: context.message,
|
||||
author: context.author,
|
||||
icon: context.icon,
|
||||
timestamp: context.timestamp,
|
||||
statistics: context.statistics,
|
||||
} satisfies ISCMHistoryItem);
|
||||
|
||||
await action.run(...args);
|
||||
}
|
||||
}
|
||||
|
||||
class HistoryItemActionRunner2 extends ActionRunner {
|
||||
constructor(private readonly getSelectedHistoryItems: () => SCMHistoryItemViewModelTreeElement[]) {
|
||||
super();
|
||||
}
|
||||
|
||||
protected override async runAction(action: IAction, context: SCMHistoryItemViewModelTreeElement): Promise<any> {
|
||||
if (!(action instanceof MenuItemAction)) {
|
||||
return super.runAction(action, context);
|
||||
}
|
||||
|
||||
const historyItem = isSCMHistoryItemTreeElement(context) ? context : context.historyItemViewModel.historyItem;
|
||||
args.push({
|
||||
id: historyItem.id,
|
||||
parentIds: historyItem.parentIds,
|
||||
message: historyItem.message,
|
||||
author: historyItem.author,
|
||||
icon: historyItem.icon,
|
||||
timestamp: historyItem.timestamp,
|
||||
statistics: historyItem.statistics,
|
||||
} satisfies ISCMHistoryItem);
|
||||
const args: (ISCMProvider | ISCMHistoryItem)[] = [];
|
||||
args.push(context.repository.provider);
|
||||
|
||||
const selection = this.getSelectedHistoryItems();
|
||||
const contextIsSelected = selection.some(s => s === context);
|
||||
if (contextIsSelected && selection.length > 1) {
|
||||
args.push(...[selection[0], selection[selection.length - 1]]
|
||||
.map(h => (
|
||||
{
|
||||
id: h.historyItemViewModel.historyItem.id,
|
||||
parentIds: h.historyItemViewModel.historyItem.parentIds,
|
||||
message: h.historyItemViewModel.historyItem.message,
|
||||
author: h.historyItemViewModel.historyItem.author,
|
||||
icon: h.historyItemViewModel.historyItem.icon,
|
||||
timestamp: h.historyItemViewModel.historyItem.timestamp,
|
||||
statistics: h.historyItemViewModel.historyItem.statistics,
|
||||
} satisfies ISCMHistoryItem)));
|
||||
} else {
|
||||
args.push({
|
||||
id: context.historyItemViewModel.historyItem.id,
|
||||
parentIds: context.historyItemViewModel.historyItem.parentIds,
|
||||
message: context.historyItemViewModel.historyItem.message,
|
||||
author: context.historyItemViewModel.historyItem.author,
|
||||
icon: context.historyItemViewModel.historyItem.icon,
|
||||
timestamp: context.historyItemViewModel.historyItem.timestamp,
|
||||
statistics: context.historyItemViewModel.historyItem.statistics,
|
||||
} satisfies ISCMHistoryItem);
|
||||
}
|
||||
|
||||
await action.run(...args);
|
||||
}
|
||||
@@ -3517,7 +3555,7 @@ export class SCMViewPane extends ViewPane {
|
||||
const menus = this.scmViewService.menus.getRepositoryMenus(element.repository.provider);
|
||||
const menu = menus.historyProviderMenu?.getHistoryItemMenu2(element);
|
||||
if (menu) {
|
||||
actionRunner = new HistoryItemActionRunner();
|
||||
actionRunner = new HistoryItemActionRunner2(() => this.getSelectedHistoryItems());
|
||||
actions = collectContextMenuActions(menu);
|
||||
}
|
||||
}
|
||||
@@ -3544,6 +3582,11 @@ export class SCMViewPane extends ViewPane {
|
||||
.filter(r => !!r && !isSCMResourceGroup(r))! as any;
|
||||
}
|
||||
|
||||
private getSelectedHistoryItems(): SCMHistoryItemViewModelTreeElement[] {
|
||||
return this.tree.getSelection()
|
||||
.filter(r => !!r && isSCMHistoryItemViewModelTreeElement(r))!;
|
||||
}
|
||||
|
||||
private getViewMode(): ViewMode {
|
||||
let mode = this.configurationService.getValue<'tree' | 'list'>('scm.defaultViewMode') === 'list' ? ViewMode.List : ViewMode.Tree;
|
||||
const storageMode = this.storageService.get(`scm.viewMode`, StorageScope.WORKSPACE) as ViewMode;
|
||||
|
||||
Reference in New Issue
Block a user