Skip to content

Commit 247a7a9

Browse files
authored
Web: Broken state for deleting branch in repo that deletes on merge (#3468)
Fixes #3453
1 parent 014f0b7 commit 247a7a9

File tree

5 files changed

+156
-232
lines changed

5 files changed

+156
-232
lines changed

src/common/uri.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,8 @@ export enum Schemes {
230230
Review = 'review',
231231
Pr = 'pr',
232232
FileChange = 'filechange',
233-
GithubPr = 'githubpr'
233+
GithubPr = 'githubpr',
234+
VscodeVfs = 'vscode-vfs' // Remote Repository
234235
}
235236

236237
export function resolvePath(from: vscode.Uri, to: string) {

src/github/activityBarViewProvider.ts

Lines changed: 5 additions & 116 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import { FolderRepositoryManager } from './folderRepositoryManager';
1313
import { GithubItemStateEnum, MergeMethod, ReviewEvent, ReviewState } from './interface';
1414
import { PullRequestModel } from './pullRequestModel';
1515
import { getDefaultMergeMethod } from './pullRequestOverview';
16+
import { PullRequestView } from './pullRequestOverviewCommon';
1617
import { isInCodespaces, parseReviewers } from './utils';
1718

1819
export class PullRequestViewProvider extends WebviewViewBase implements vscode.WebviewViewProvider {
@@ -292,123 +293,11 @@ export class PullRequestViewProvider extends WebviewViewBase implements vscode.W
292293
}
293294

294295
private async deleteBranch(message: IRequestMessage<any>) {
295-
const branchInfo = await this._folderRepositoryManager.getBranchNameForPullRequest(this._item);
296-
const actions: (vscode.QuickPickItem & { type: 'upstream' | 'local' | 'remote' | 'suspend' })[] = [];
297-
298-
if (this._item.isResolved()) {
299-
const branchHeadRef = this._item.head.ref;
300-
301-
const defaultBranch = await this._folderRepositoryManager.getPullRequestRepositoryDefaultBranch(this._item);
302-
const isDefaultBranch = defaultBranch === this._item.head.ref;
303-
if (!isDefaultBranch) {
304-
actions.push({
305-
label: `Delete remote branch ${this._item.remote.remoteName}/${branchHeadRef}`,
306-
description: `${this._item.remote.normalizedHost}/${this._item.remote.owner}/${this._item.remote.repositoryName}`,
307-
type: 'upstream',
308-
picked: true,
309-
});
310-
}
311-
}
312-
313-
if (branchInfo) {
314-
const preferredLocalBranchDeletionMethod = vscode.workspace
315-
.getConfiguration('githubPullRequests')
316-
.get<boolean>('defaultDeletionMethod.selectLocalBranch');
317-
actions.push({
318-
label: `Delete local branch ${branchInfo.branch}`,
319-
type: 'local',
320-
picked: !!preferredLocalBranchDeletionMethod,
321-
});
322-
323-
const preferredRemoteDeletionMethod = vscode.workspace
324-
.getConfiguration('githubPullRequests')
325-
.get<boolean>('defaultDeletionMethod.selectRemote');
326-
327-
if (branchInfo.remote && branchInfo.createdForPullRequest && !branchInfo.remoteInUse) {
328-
actions.push({
329-
label: `Delete remote ${branchInfo.remote}, which is no longer used by any other branch`,
330-
type: 'remote',
331-
picked: !!preferredRemoteDeletionMethod,
332-
});
333-
}
334-
}
335-
336-
if (vscode.env.remoteName === 'codespaces') {
337-
actions.push({
338-
label: 'Suspend Codespace',
339-
type: 'suspend'
340-
});
341-
}
342-
343-
if (!actions.length) {
344-
vscode.window.showWarningMessage(
345-
`There is no longer an upstream or local branch for Pull Request #${this._item.number}`,
346-
);
347-
this._replyMessage(message, {
348-
cancelled: true,
349-
});
350-
351-
return;
352-
}
353-
354-
const selectedActions = await vscode.window.showQuickPick(actions, {
355-
canPickMany: true,
356-
ignoreFocusOut: true,
357-
});
358-
359-
const deletedBranchTypes: string[] = [];
360-
361-
if (selectedActions) {
362-
const isBranchActive = this._item.equals(this._folderRepositoryManager.activePullRequest);
363-
364-
const promises = selectedActions.map(async action => {
365-
switch (action.type) {
366-
case 'upstream':
367-
await this._folderRepositoryManager.deleteBranch(this._item);
368-
deletedBranchTypes.push(action.type);
369-
return this._folderRepositoryManager.repository.fetch({ prune: true });
370-
case 'local':
371-
if (isBranchActive) {
372-
if (this._folderRepositoryManager.repository.state.workingTreeChanges.length) {
373-
const response = await vscode.window.showWarningMessage(
374-
`Your local changes will be lost, do you want to continue?`,
375-
{ modal: true },
376-
'Yes',
377-
);
378-
if (response === 'Yes') {
379-
await vscode.commands.executeCommand('git.cleanAll');
380-
} else {
381-
return;
382-
}
383-
}
384-
const defaultBranch = await this._folderRepositoryManager.getPullRequestRepositoryDefaultBranch(
385-
this._item,
386-
);
387-
await this._folderRepositoryManager.repository.checkout(defaultBranch);
388-
}
389-
await this._folderRepositoryManager.repository.deleteBranch(branchInfo!.branch, true);
390-
return deletedBranchTypes.push(action.type);
391-
case 'remote':
392-
await this._folderRepositoryManager.repository.removeRemote(branchInfo!.remote!);
393-
return deletedBranchTypes.push(action.type);
394-
case 'suspend':
395-
await vscode.commands.executeCommand('github.codespaces.disconnectSuspend');
396-
return deletedBranchTypes.push(action.type);
397-
}
398-
});
399-
400-
await Promise.all(promises);
401-
402-
vscode.commands.executeCommand('pr.refreshList');
403-
404-
this._postMessage({
405-
command: 'pr.deleteBranch',
406-
branchTypes: deletedBranchTypes
407-
});
296+
const result = await PullRequestView.deleteBranch(this._folderRepositoryManager, this._item);
297+
if (result.isReply) {
298+
this._replyMessage(message, result.message);
408299
} else {
409-
this._replyMessage(message, {
410-
cancelled: true,
411-
});
300+
this._postMessage(result.message);
412301
}
413302
}
414303

src/github/pullRequestOverview.ts

Lines changed: 6 additions & 113 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import {
2525
} from './interface';
2626
import { IssueOverviewPanel } from './issueOverview';
2727
import { PullRequestModel } from './pullRequestModel';
28+
import { PullRequestView } from './pullRequestOverviewCommon';
2829
import { isInCodespaces, parseReviewers } from './utils';
2930

3031
type MilestoneQuickPickItem = vscode.QuickPickItem & { id: string; milestone: IMilestone };
@@ -645,120 +646,12 @@ export class PullRequestOverviewPanel extends IssueOverviewPanel<PullRequestMode
645646
}
646647

647648
private async deleteBranch(message: IRequestMessage<any>) {
648-
const branchInfo = await this._folderRepositoryManager.getBranchNameForPullRequest(this._item);
649-
const actions: (vscode.QuickPickItem & { type: 'upstream' | 'local' | 'remote' | 'suspend' })[] = [];
650-
651-
if (this._item.isResolved()) {
652-
const branchHeadRef = this._item.head.ref;
653-
654-
const isDefaultBranch = this._repositoryDefaultBranch === this._item.head.ref;
655-
if (!isDefaultBranch && !this._item.isRemoteHeadDeleted) {
656-
actions.push({
657-
label: `Delete remote branch ${this._item.remote.remoteName}/${branchHeadRef}`,
658-
description: `${this._item.remote.normalizedHost}/${this._item.remote.owner}/${this._item.remote.repositoryName}`,
659-
type: 'upstream',
660-
picked: true,
661-
});
662-
}
663-
}
664-
665-
if (branchInfo) {
666-
const preferredLocalBranchDeletionMethod = vscode.workspace
667-
.getConfiguration('githubPullRequests')
668-
.get<boolean>('defaultDeletionMethod.selectLocalBranch');
669-
actions.push({
670-
label: `Delete local branch ${branchInfo.branch}`,
671-
type: 'local',
672-
picked: !!preferredLocalBranchDeletionMethod,
673-
});
674-
675-
const preferredRemoteDeletionMethod = vscode.workspace
676-
.getConfiguration('githubPullRequests')
677-
.get<boolean>('defaultDeletionMethod.selectRemote');
678-
679-
if (branchInfo.remote && branchInfo.createdForPullRequest && !branchInfo.remoteInUse) {
680-
actions.push({
681-
label: `Delete remote ${branchInfo.remote}, which is no longer used by any other branch`,
682-
type: 'remote',
683-
picked: !!preferredRemoteDeletionMethod,
684-
});
685-
}
686-
}
687-
688-
if (vscode.env.remoteName === 'codespaces') {
689-
actions.push({
690-
label: 'Suspend Codespace',
691-
type: 'suspend'
692-
});
693-
}
694-
695-
if (!actions.length) {
696-
vscode.window.showWarningMessage(
697-
`There is no longer an upstream or local branch for Pull Request #${this._item.number}`,
698-
);
699-
this._replyMessage(message, {
700-
cancelled: true,
701-
});
702-
703-
return;
704-
}
705-
706-
const selectedActions = await vscode.window.showQuickPick(actions, {
707-
canPickMany: true,
708-
ignoreFocusOut: true,
709-
});
710-
711-
const deletedBranchTypes: string[] = [];
712-
713-
if (selectedActions) {
714-
const isBranchActive = this._item.equals(this._folderRepositoryManager.activePullRequest);
715-
716-
const promises = selectedActions.map(async action => {
717-
switch (action.type) {
718-
case 'upstream':
719-
await this._folderRepositoryManager.deleteBranch(this._item);
720-
deletedBranchTypes.push(action.type);
721-
return this._folderRepositoryManager.repository.fetch({ prune: true });
722-
case 'local':
723-
if (isBranchActive) {
724-
if (this._folderRepositoryManager.repository.state.workingTreeChanges.length) {
725-
const response = await vscode.window.showWarningMessage(
726-
`Your local changes will be lost, do you want to continue?`,
727-
{ modal: true },
728-
'Yes',
729-
);
730-
if (response === 'Yes') {
731-
await vscode.commands.executeCommand('git.cleanAll');
732-
} else {
733-
return;
734-
}
735-
}
736-
await this._folderRepositoryManager.repository.checkout(this._repositoryDefaultBranch);
737-
}
738-
await this._folderRepositoryManager.repository.deleteBranch(branchInfo!.branch, true);
739-
return deletedBranchTypes.push(action.type);
740-
case 'remote':
741-
deletedBranchTypes.push(action.type);
742-
return this._folderRepositoryManager.repository.removeRemote(branchInfo!.remote!);
743-
case 'suspend':
744-
deletedBranchTypes.push(action.type);
745-
return vscode.commands.executeCommand('github.codespaces.disconnectSuspend');
746-
}
747-
});
748-
749-
await Promise.all(promises);
750-
751-
this.refreshPanel();
752-
vscode.commands.executeCommand('pr.refreshList');
753-
754-
this._postMessage({
755-
command: 'pr.deleteBranch',
756-
branchTypes: deletedBranchTypes
757-
});
649+
const result = await PullRequestView.deleteBranch(this._folderRepositoryManager, this._item);
650+
if (result.isReply) {
651+
this._replyMessage(message, result.message);
758652
} else {
759-
this._replyMessage(message, {
760-
cancelled: true,
761-
});
653+
this.refreshPanel();
654+
this._postMessage(result.message);
762655
}
763656
}
764657

0 commit comments

Comments
 (0)