Git - unify compare commands for the graph (#273771)

* Git - unify compare commands for the graph

* Update placeholder

* More changes
This commit is contained in:
Ladislau Szomoru
2025-10-28 17:00:51 +01:00
committed by GitHub
parent 23894eb833
commit 90627f0950
3 changed files with 70 additions and 96 deletions

View File

@@ -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": [

View File

@@ -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",

View File

@@ -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<void> {
await this._compareRef(repository, historyItem, historyItemRefId);
@command('git.graph.compareRef', { repository: true })
async compareBranch(repository: Repository, historyItem?: SourceControlHistoryItem): Promise<void> {
if (!repository || !historyItem) {
return;
}
const config = workspace.getConfiguration('git');
const showRefDetails = config.get<boolean>('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<void> {
await this._compareRef(repository, historyItem, historyItemRefId);
}
@command('git.deleteRemoteTag', { repository: true })
async deleteRemoteTag(repository: Repository): Promise<void> {
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<void> {
const historyItemRef = historyItem?.references?.find(r => r.id === historyItemRefId);
if (!historyItemRefId || !historyItemRef) {
return;
}
const config = workspace.getConfiguration('git');
const showRefDetails = config.get<boolean>('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<any>;