handle git branch delete error ("not fully merged")

This commit is contained in:
Maik Riechert 2017-05-06 16:23:50 +01:00 committed by Dirk Baeumer
parent b96478ebcc
commit b348a0b780
3 changed files with 45 additions and 27 deletions

View file

@ -62,21 +62,18 @@ class CheckoutRemoteHeadItem extends CheckoutItem {
class BranchDeleteItem implements QuickPickItem {
protected get shortCommit(): string { return (this.ref.commit || '').substr(0, 8); }
protected get treeish(): string | undefined { return this.ref.name; }
get label(): string { return this.ref.name || this.shortCommit; }
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(protected ref: Ref) { }
constructor(private ref: Ref) { }
async run(model: Model): Promise<void> {
const ref = this.treeish;
if (!ref) {
async run(model: Model, force?: boolean): Promise<void> {
if (!this.branchName) {
return;
}
await model.deleteBranch(ref);
await model.deleteBranch(this.branchName, force);
}
}
@ -720,22 +717,40 @@ export class CommandCenter {
}
@command('git.deleteBranch')
async deleteBranch(branchName: string): Promise<void> {
if (typeof branchName === 'string') {
return await this.model.deleteBranch(branchName);
}
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));
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 = 'Select a branch to delete';
const choice = await window.showQuickPick<BranchDeleteItem>(heads, { placeHolder });
const placeHolder = 'Select a branch to delete';
const choice = await window.showQuickPick<BranchDeleteItem>(heads, { placeHolder });
if (!choice) {
return;
if (!choice) {
return;
}
name = choice.branchName || '';
run = force => choice.run(this.model, force);
}
await choice.run(this.model);
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')

View file

@ -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 {
@ -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;
@ -650,8 +653,8 @@ export class Repository {
await this.run(args);
}
async deleteBranch(name: string): Promise<void> {
const args = ['branch', '-d', name];
async deleteBranch(name: string, force?: boolean): Promise<void> {
const args = ['branch', force ? '-D' : '-d', name];
await this.run(args);
}

View file

@ -454,8 +454,8 @@ export class Model implements Disposable {
await this.run(Operation.Branch, () => this.repository.branch(name, true));
}
async deleteBranch(name: string): Promise<void> {
await this.run(Operation.DeleteBranch, () => this.repository.deleteBranch(name));
async deleteBranch(name: string, force?: boolean): Promise<void> {
await this.run(Operation.DeleteBranch, () => this.repository.deleteBranch(name, force));
}
async checkout(treeish: string): Promise<void> {