Skip to content

Commit a32dacc

Browse files
author
Rachel Macfarlane
committed
Remove remote created by extension when deleting branch if nothing else references it, #143
1 parent f43a077 commit a32dacc

5 files changed

Lines changed: 42 additions & 13 deletions

File tree

src/commands.ts

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@ import { fromReviewUri } from './common/uri';
1111
import { FileChangeNode } from './view/treeNodes/fileChangeNode';
1212
import { PRNode } from './view/treeNodes/pullRequestNode';
1313
import { IPullRequestManager, IPullRequestModel, IPullRequest } from './github/interface';
14-
import { exec } from './common/git';
1514

1615
const _onDidClosePR = new vscode.EventEmitter<IPullRequest>();
1716
export const onDidClosePR: vscode.Event<IPullRequest> = _onDidClosePR.event;
@@ -51,14 +50,13 @@ export function registerCommands(context: vscode.ExtensionContext, prManager: IP
5150
}));
5251

5352
context.subscriptions.push(vscode.commands.registerCommand('pr.deleteLocalBranch', async (e: PRNode) => {
54-
const result = await exec(['branch', '-D', e.pullRequestModel.localBranchName], { cwd: vscode.workspace.rootPath });
55-
56-
if (result.stderr) {
57-
vscode.window.showErrorMessage(`Deleting local pull request branch failed: ${result.stderr}`);
58-
return;
53+
const pullRequestModel = ensurePR(prManager, e);
54+
try {
55+
await prManager.deleteLocalPullRequest(pullRequestModel);
56+
vscode.commands.executeCommand('pr.refreshList');
57+
} catch (e) {
58+
vscode.window.showErrorMessage(`Deleting local pull request branch failed: ${e}`);
5959
}
60-
61-
vscode.commands.executeCommand('pr.refreshList');
6260
}));
6361

6462
context.subscriptions.push(vscode.commands.registerCommand('pr.pick', async (pr: PRNode | IPullRequestModel) => {

src/common/repository.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -237,7 +237,7 @@ export class Repository {
237237
return [];
238238
}
239239

240-
return result.stdout.trim().split(/\r|\n|\r\n/).map(branchName => {
240+
return result.stdout.trimRight().split(/\r|\n|\r\n/).map(branchName => {
241241
return branchName.substr(2);
242242
});
243243
}

src/github/interface.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@ export interface IPullRequestManager {
126126
activePullRequest?: IPullRequestModel;
127127
readonly onDidChangeActivePullRequest: vscode.Event<void>;
128128
getLocalPullRequests(): Promise<IPullRequestModel[]>;
129+
deleteLocalPullRequest(pullRequest: IPullRequestModel): Promise<void>;
129130
getPullRequests(type: PRType, options?: IPullRequestsPagingOptions):Promise<[IPullRequestModel[], boolean]>;
130131
mayHaveMorePages(): boolean;
131132
getPullRequestComments(pullRequest: IPullRequestModel): Promise<Comment[]>;

src/github/pullRequestGitHelper.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,12 +151,11 @@ export class PullRequestGitHelper {
151151
Logger.appendLine(`GitHelper> create remote for ${cloneUrl}.`)
152152

153153
let remotes = repository.remotes;
154-
155-
remotes.forEach(remote => {
154+
for (let remote of remotes) {
156155
if (new Protocol(remote.url).equals(cloneUrl)) {
157-
return remote.repositoryName;
156+
return remote.remoteName;
158157
}
159-
});
158+
}
160159

161160
let remoteName = PullRequestGitHelper.getUniqueRemoteName(repository, cloneUrl.owner);
162161
await repository.addRemote(remoteName, cloneUrl.normalizeUri().toString());

src/github/pullRequestManager.ts

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,37 @@ export class PullRequestManager implements IPullRequestManager {
118118
});
119119
}
120120

121+
async deleteLocalPullRequest(pullRequest: PullRequestModel): Promise<void> {
122+
const remoteName = await this._repository.getConfig(`branch.${pullRequest.localBranchName}.remote`);
123+
if (!remoteName) {
124+
throw new Error('Unable to find remote for branch');
125+
}
126+
127+
const result = await this._repository.run(['branch', '-D', pullRequest.localBranchName]);
128+
if (result.stderr) {
129+
throw new Error(result.stderr);
130+
}
131+
132+
// If the extension created a remote for the branch, remove it if there are no other branches associated with it
133+
const isPRRemote = await PullRequestGitHelper.isRemoteCreatedForPullRequest(this._repository, remoteName);
134+
if (isPRRemote) {
135+
const configKeyValues = await this._repository.run(['config', '--local', '-l']);
136+
if (configKeyValues.stderr) {
137+
throw new Error(configKeyValues.stderr);
138+
}
139+
140+
const result = configKeyValues.stdout.trim();
141+
const hasOtherAssociatedBranches = new RegExp(`^branch.*\.remote=${remoteName}$`, 'm').test(result);
142+
143+
if (!hasOtherAssociatedBranches) {
144+
const remoteResult = await this._repository.run(['remote', 'remove', remoteName]);
145+
if (remoteResult.stderr) {
146+
throw new Error(remoteResult.stderr);
147+
}
148+
}
149+
}
150+
}
151+
121152
async getPullRequests(type: PRType, options: IPullRequestsPagingOptions = { fetchNextPage: false }): Promise<[IPullRequestModel[], boolean]> {
122153
let githubRepositories = this._githubRepositories;
123154

0 commit comments

Comments
 (0)