Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add git delete branch command #25862

Merged
merged 4 commits into from
May 24, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
9 changes: 9 additions & 0 deletions extensions/git/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,11 @@
"title": "%command.branch%",
"category": "Git"
},
{
"command": "git.deleteBranch",
"title": "%command.deleteBranch%",
"category": "Git"
},
{
"command": "git.pull",
"title": "%command.pull%",
Expand Down Expand Up @@ -298,6 +303,10 @@
"command": "git.branch",
"when": "config.git.enabled && scmProvider == git && gitState == idle"
},
{
"command": "git.deleteBranch",
"when": "config.git.enabled && scmProvider == git && gitState == idle"
},
{
"command": "git.pull",
"when": "config.git.enabled && scmProvider == git && gitState == idle"
Expand Down
1 change: 1 addition & 0 deletions extensions/git/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
"command.undoCommit": "Undo Last Commit",
"command.checkout": "Checkout to...",
"command.branch": "Create Branch...",
"command.deleteBranch": "Delete Branch...",
"command.pull": "Pull",
"command.pullRebase": "Pull (Rebase)",
"command.push": "Push",
Expand Down
54 changes: 54 additions & 0 deletions extensions/git/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,23 @@ class CheckoutRemoteHeadItem extends CheckoutItem {
}
}

class BranchDeleteItem implements QuickPickItem {

private get shortCommit(): string { return (this.ref.commit || '').substr(0, 8); }
get branchName(): string | undefined { return this.ref.name; }
get label(): string { return this.branchName || ''; }
get description(): string { return this.shortCommit; }

constructor(private ref: Ref) { }

async run(model: Model, force?: boolean): Promise<void> {
if (!this.branchName) {
return;
}
await model.deleteBranch(this.branchName, force);
}
}

interface Command {
commandId: string;
key: string;
Expand Down Expand Up @@ -699,6 +716,43 @@ export class CommandCenter {
await this.model.branch(name);
}

@command('git.deleteBranch')
async deleteBranch(name: string, force?: boolean): Promise<void> {
let run: (force?: boolean) => Promise<void>;
if (typeof name === 'string') {
run = force => this.model.deleteBranch(name, force);
} else {
const currentHead = this.model.HEAD && this.model.HEAD.name;
const heads = this.model.refs.filter(ref => ref.type === RefType.Head && ref.name !== currentHead)
.map(ref => new BranchDeleteItem(ref));

const placeHolder = localize('select branch to delete', 'Select a branch to delete');
const choice = await window.showQuickPick<BranchDeleteItem>(heads, { placeHolder });

if (!choice || !choice.branchName) {
return;
}
name = choice.branchName;
run = force => choice.run(this.model, force);
}

try {
await run(force);
} catch (err) {
if (err.gitErrorCode !== GitErrorCodes.BranchNotFullyMerged) {
throw err;
}

const message = localize('confirm force delete branch', "The branch '{0}' is not fully merged. Delete anyway?", name);
const yes = localize('delete branch', "Delete Branch");
const pick = await window.showWarningMessage(message, yes);

if (pick === yes) {
await run(true);
}
}
}

@command('git.pull')
async pull(): Promise<void> {
const remotes = this.model.remotes;
Expand Down
10 changes: 9 additions & 1 deletion extensions/git/src/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ export const GitErrorCodes = {
CantCreatePipe: 'CantCreatePipe',
CantAccessRemote: 'CantAccessRemote',
RepositoryNotFound: 'RepositoryNotFound',
RepositoryIsLocked: 'RepositoryIsLocked'
RepositoryIsLocked: 'RepositoryIsLocked',
BranchNotFullyMerged: 'BranchNotFullyMerged'
};

function getGitErrorCode(stderr: string): string | undefined {
Expand All @@ -291,6 +292,8 @@ function getGitErrorCode(stderr: string): string | undefined {
return GitErrorCodes.RepositoryNotFound;
} else if (/unable to access/.test(stderr)) {
return GitErrorCodes.CantAccessRemote;
} else if (/branch '.+' is not fully merged/.test(stderr)) {
return GitErrorCodes.BranchNotFullyMerged;
}

return void 0;
Expand Down Expand Up @@ -650,6 +653,11 @@ export class Repository {
await this.run(args);
}

async deleteBranch(name: string, force?: boolean): Promise<void> {
const args = ['branch', force ? '-D' : '-d', name];
await this.run(args);
}

async clean(paths: string[]): Promise<void> {
const pathsByGroup = groupBy(paths, p => path.dirname(p));
const groups = Object.keys(pathsByGroup).map(k => pathsByGroup[k]);
Expand Down
7 changes: 6 additions & 1 deletion extensions/git/src/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,8 @@ export enum Operation {
Init = 1 << 12,
Show = 1 << 13,
Stage = 1 << 14,
GetCommitTemplate = 1 << 15
GetCommitTemplate = 1 << 15,
DeleteBranch = 1 << 16
}

// function getOperationName(operation: Operation): string {
Expand Down Expand Up @@ -454,6 +455,10 @@ export class Model implements Disposable {
await this.run(Operation.Branch, () => this.repository.branch(name, true));
}

async deleteBranch(name: string, force?: boolean): Promise<void> {
await this.run(Operation.DeleteBranch, () => this.repository.deleteBranch(name, force));
}

async checkout(treeish: string): Promise<void> {
await this.run(Operation.Checkout, () => this.repository.checkout(treeish, []));
}
Expand Down