From 90627f095003ceace999409d014a52dbf5e45e08 Mon Sep 17 00:00:00 2001 From: Ladislau Szomoru <3372902+lszomoru@users.noreply.github.com> Date: Tue, 28 Oct 2025 17:00:51 +0100 Subject: [PATCH] Git - unify compare commands for the graph (#273771) * Git - unify compare commands for the graph * Update placeholder * More changes --- extensions/git/package.json | 39 ++++------ extensions/git/package.nls.json | 3 +- extensions/git/src/commands.ts | 124 +++++++++++++++----------------- 3 files changed, 70 insertions(+), 96 deletions(-) diff --git a/extensions/git/package.json b/extensions/git/package.json index 775a19bd5c6..7e6339d29dc 100644 --- a/extensions/git/package.json +++ b/extensions/git/package.json @@ -514,12 +514,6 @@ "category": "Git", "enablement": "!operationInProgress" }, - { - "command": "git.graph.compareBranch", - "title": "%command.graphCompareBranch%", - "category": "Git", - "enablement": "!operationInProgress" - }, { "command": "git.deleteRemoteBranch", "title": "%command.deleteRemoteBranch%", @@ -592,12 +586,6 @@ "category": "Git", "enablement": "!operationInProgress" }, - { - "command": "git.graph.compareTag", - "title": "%command.graphCompareTag%", - "category": "Git", - "enablement": "!operationInProgress" - }, { "command": "git.deleteRemoteTag", "title": "%command.deleteRemoteTag%", @@ -1010,6 +998,12 @@ "command": "git.blame.toggleStatusBarItem", "title": "%command.blameToggleStatusBarItem%", "category": "Git" + }, + { + "command": "git.graph.compareRef", + "title": "%command.graphCompareRef%", + "category": "Git", + "enablement": "!operationInProgress" } ], "continueEditSession": [ @@ -1607,17 +1601,13 @@ "when": "false" }, { - "command": "git.graph.compareBranch", + "command": "git.graph.compareRef", "when": "false" }, { "command": "git.graph.deleteTag", "when": "false" }, - { - "command": "git.graph.compareTag", - "when": "false" - }, { "command": "git.graph.cherryPick", "when": "false" @@ -2263,6 +2253,11 @@ "when": "scmProvider == git", "group": "4_modify@1" }, + { + "command": "git.graph.compareRef", + "when": "scmProvider == git", + "group": "5_compare@1" + }, { "command": "git.copyCommitId", "when": "scmProvider == git && !listMultiSelection", @@ -2285,20 +2280,10 @@ "when": "scmProvider == git && scmHistoryItemRef =~ /^refs\\/heads\\/|^refs\\/remotes\\//", "group": "2_branch@2" }, - { - "command": "git.graph.compareBranch", - "when": "scmProvider == git && scmHistoryItemRef =~ /^refs\\/heads\\//", - "group": "2_branch@3" - }, { "command": "git.graph.deleteTag", "when": "scmProvider == git && scmHistoryItemRef =~ /^refs\\/tags\\//", "group": "3_tag@2" - }, - { - "command": "git.graph.compareTag", - "when": "scmProvider == git && scmHistoryItemRef =~ /^refs\\/tags\\//", - "group": "3_tag@3" } ], "editor/title": [ diff --git a/extensions/git/package.nls.json b/extensions/git/package.nls.json index 924d219a095..80ffec8c433 100644 --- a/extensions/git/package.nls.json +++ b/extensions/git/package.nls.json @@ -135,10 +135,9 @@ "command.graphCheckout": "Checkout", "command.graphCheckoutDetached": "Checkout (Detached)", "command.graphCherryPick": "Cherry Pick", - "command.graphCompareBranch": "Compare Branch...", "command.graphDeleteBranch": "Delete Branch", "command.graphDeleteTag": "Delete Tag", - "command.graphCompareTag": "Compare Tag...", + "command.graphCompareRef": "Compare With...", "command.blameToggleEditorDecoration": "Toggle Git Blame Editor Decoration", "command.blameToggleStatusBarItem": "Toggle Git Blame Status Bar Item", "command.api.getRepositories": "Get Repositories", diff --git a/extensions/git/src/commands.ts b/extensions/git/src/commands.ts index baab4069724..b6ff0a6ff30 100644 --- a/extensions/git/src/commands.ts +++ b/extensions/git/src/commands.ts @@ -3109,9 +3109,63 @@ export class CommandCenter { await this._deleteBranch(repository, remoteName, refName, { remote: true }); } - @command('git.graph.compareBranch', { repository: true }) - async compareBranch(repository: Repository, historyItem?: SourceControlHistoryItem, historyItemRefId?: string): Promise { - await this._compareRef(repository, historyItem, historyItemRefId); + @command('git.graph.compareRef', { repository: true }) + async compareBranch(repository: Repository, historyItem?: SourceControlHistoryItem): Promise { + if (!repository || !historyItem) { + return; + } + + const config = workspace.getConfiguration('git'); + const showRefDetails = config.get('showReferenceDetails') === true; + + const getRefPicks = async () => { + const refs = await repository.getRefs({ includeCommitDetails: showRefDetails }); + const processors = [ + new RefProcessor(RefType.Head, BranchItem), + new RefProcessor(RefType.RemoteHead, BranchItem), + new RefProcessor(RefType.Tag, BranchItem) + ]; + + const itemsProcessor = new RefItemsProcessor(repository, processors); + return itemsProcessor.processRefs(refs); + }; + + const placeHolder = l10n.t('Select a reference to compare with'); + const sourceRef = await this.pickRef(getRefPicks(), placeHolder); + + if (!(sourceRef instanceof BranchItem) || !sourceRef.ref.commit) { + return; + } + + if (historyItem.id === sourceRef.ref.commit) { + window.showInformationMessage(l10n.t('The selected references are the same.')); + return; + } + + try { + const sourceCommit = sourceRef.ref.commit; + const changes = await repository.diffTrees(sourceCommit, historyItem.id); + + if (changes.length === 0) { + window.showInformationMessage(l10n.t('The selected references have no differences.')); + return; + } + + const resources = changes.map(change => toMultiFileDiffEditorUris(change, sourceCommit, historyItem.id)); + const title = `${sourceRef.ref.name ?? sourceCommit} ↔ ${historyItem.references?.[0].name ?? historyItem.id}`; + const multiDiffSourceUri = Uri.from({ + scheme: 'git-ref-compare', + path: `${repository.root}/${sourceCommit}..${historyItem.id}` + }); + + await commands.executeCommand('_workbench.openMultiDiffEditor', { + multiDiffSourceUri, + title, + resources + }); + } catch (err) { + throw new Error(l10n.t('Failed to compare references: {0}', err.message ?? err)); + } } @command('git.deleteRemoteBranch', { repository: true }) @@ -3752,11 +3806,6 @@ export class CommandCenter { await repository.deleteTag(historyItemRef.name); } - @command('git.graph.compareTag', { repository: true }) - async compareTags(repository: Repository, historyItem?: SourceControlHistoryItem, historyItemRefId?: string): Promise { - await this._compareRef(repository, historyItem, historyItemRefId); - } - @command('git.deleteRemoteTag', { repository: true }) async deleteRemoteTag(repository: Repository): Promise { const config = workspace.getConfiguration('git'); @@ -5096,65 +5145,6 @@ export class CommandCenter { config.update(setting, !enabled, true); } - async _compareRef(repository: Repository, historyItem?: SourceControlHistoryItem, historyItemRefId?: string): Promise { - const historyItemRef = historyItem?.references?.find(r => r.id === historyItemRefId); - if (!historyItemRefId || !historyItemRef) { - return; - } - - const config = workspace.getConfiguration('git'); - const showRefDetails = config.get('showReferenceDetails') === true; - - const getRefPicks = async () => { - const refs = await repository.getRefs({ includeCommitDetails: showRefDetails }); - const processors = [ - new RefProcessor(RefType.Head, BranchItem), - new RefProcessor(RefType.RemoteHead, BranchItem), - new RefProcessor(RefType.Tag, BranchItem) - ]; - - const itemsProcessor = new RefItemsProcessor(repository, processors); - return itemsProcessor.processRefs(refs); - }; - - const placeHolder = l10n.t('Select a source reference to compare with'); - const sourceRef = await this.pickRef(getRefPicks(), placeHolder); - - if (!(sourceRef instanceof BranchItem)) { - return; - } - - if (historyItemRef.id === sourceRef.refId) { - window.showInformationMessage(l10n.t('The selected references are the same.')); - return; - } - - try { - const changes = await repository.diffTrees(sourceRef.refId, historyItemRef.id); - - if (changes.length === 0) { - window.showInformationMessage(l10n.t('The selected references have no differences.')); - return; - } - - const resources = changes.map(change => toMultiFileDiffEditorUris(change, sourceRef.refId, historyItemRef.id)); - - const title = `${sourceRef.ref.name} ↔ ${historyItemRef.name}`; - const multiDiffSourceUri = Uri.from({ - scheme: 'git-ref-compare', - path: `${repository.root}/${sourceRef.refId}..${historyItemRef.id}` - }); - - await commands.executeCommand('_workbench.openMultiDiffEditor', { - multiDiffSourceUri, - title, - resources - }); - } catch (err) { - throw new Error(l10n.t('Failed to compare references: {0}', err.message ?? err)); - } - } - private createCommand(id: string, key: string, method: Function, options: ScmCommandOptions): (...args: any[]) => any { const result = (...args: any[]) => { let result: Promise;