Skip to content

Commit 1536522

Browse files
committed
add deleteBranch
1 parent 279a32b commit 1536522

File tree

6 files changed

+110
-53
lines changed

6 files changed

+110
-53
lines changed

src/commands/git/branch.ts

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -543,10 +543,17 @@ export class BranchGitCommand extends QuickCommand {
543543
state.flags = result;
544544

545545
endSteps(state);
546-
state.repo.branchDelete(state.references, {
547-
force: state.flags.includes('--force'),
548-
remote: state.flags.includes('--remotes'),
549-
});
546+
547+
try {
548+
await state.repo.git.deleteBranch(state.references, {
549+
force: state.flags.includes('--force'),
550+
remote: state.flags.includes('--remotes'),
551+
});
552+
} catch (ex) {
553+
Logger.error(ex);
554+
// TODO likely need some better error handling here
555+
return showGenericErrorMessage('Unable to delete branch');
556+
}
550557
}
551558
}
552559

src/env/node/git/git.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ import { GitErrorHandling } from '../../../git/commandOptions';
1212
import {
1313
BlameIgnoreRevsFileBadRevisionError,
1414
BlameIgnoreRevsFileError,
15+
BranchError,
16+
BranchErrorReason,
1517
CherryPickError,
1618
CherryPickErrorReason,
1719
FetchError,
@@ -520,7 +522,7 @@ export class Git {
520522
}
521523
}
522524

523-
branch(repoPath: string, ...args: string[]) {
525+
async branch(repoPath: string, ...args: string[]): Promise<void> {
524526
return this.git<string>({ cwd: repoPath }, 'branch', ...args);
525527
}
526528

@@ -976,6 +978,10 @@ export class Git {
976978
publish?: boolean;
977979
remote?: string;
978980
upstream?: string;
981+
delete?: {
982+
remote: string;
983+
branches: string[];
984+
};
979985
},
980986
): Promise<void> {
981987
const params = ['push'];
@@ -1001,8 +1007,10 @@ export class Git {
10011007
} else {
10021008
params.push(options.remote, options.branch);
10031009
}
1004-
} else if (options.remote) {
1010+
} else if (options.remote != null) {
10051011
params.push(options.remote);
1012+
} else if (options.delete != null) {
1013+
params.push('-d', options.delete.remote, ...options.delete.branches);
10061014
}
10071015

10081016
try {

src/env/node/git/localGitProvider.ts

Lines changed: 62 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -188,7 +188,17 @@ import { countStringLength, filterMap } from '../../../system/array';
188188
import { gate } from '../../../system/decorators/gate';
189189
import { debug, log } from '../../../system/decorators/log';
190190
import { debounce } from '../../../system/function';
191-
import { filterMap as filterMapIterable, find, first, join, last, map, skip, some } from '../../../system/iterable';
191+
import {
192+
filterMap as filterMapIterable,
193+
find,
194+
first,
195+
groupByMap,
196+
join,
197+
last,
198+
map,
199+
skip,
200+
some,
201+
} from '../../../system/iterable';
192202
import { Logger } from '../../../system/logger';
193203
import type { LogScope } from '../../../system/logger.scope';
194204
import { getLogScope, setLogScopeExit } from '../../../system/logger.scope';
@@ -1264,6 +1274,57 @@ export class LocalGitProvider implements GitProvider, Disposable {
12641274
await this.git.branch(repoPath, '-m', oldName, newName);
12651275
}
12661276

1277+
@log()
1278+
async deleteBranch(
1279+
repoPath: string,
1280+
branches: GitBranchReference[],
1281+
options: { force?: boolean; remote?: boolean },
1282+
): Promise<void> {
1283+
const localBranches = branches.filter((b: GitBranchReference) => !b.remote);
1284+
if (localBranches.length !== 0) {
1285+
const args = ['--delete'];
1286+
if (options.force) {
1287+
args.push('--force');
1288+
}
1289+
1290+
await this.git.branch(repoPath, ...args, ...branches.map((b: GitBranchReference) => b.ref));
1291+
1292+
if (options.remote) {
1293+
const trackingBranches = localBranches.filter(b => b.upstream != null);
1294+
if (trackingBranches.length !== 0) {
1295+
const branchesByOrigin = groupByMap(trackingBranches, b =>
1296+
getRemoteNameFromBranchName(b.upstream!.name),
1297+
);
1298+
1299+
for (const [remote, branches] of branchesByOrigin.entries()) {
1300+
await this.git.push(repoPath, {
1301+
delete: {
1302+
remote: remote,
1303+
branches: branches.map(b => getBranchNameWithoutRemote(b.upstream!.name)),
1304+
},
1305+
});
1306+
}
1307+
}
1308+
}
1309+
}
1310+
1311+
const remoteBranches = branches.filter((b: GitBranchReference) => b.remote);
1312+
if (remoteBranches.length !== 0) {
1313+
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));
1314+
1315+
for (const [remote, branches] of branchesByOrigin.entries()) {
1316+
await this.git.push(repoPath, {
1317+
delete: {
1318+
remote: remote,
1319+
branches: branches.map((b: GitBranchReference) =>
1320+
b.remote ? getBranchNameWithoutRemote(b.name) : b.name,
1321+
),
1322+
},
1323+
});
1324+
}
1325+
}
1326+
}
1327+
12671328
@log()
12681329
async createTag(repoPath: string, name: string, ref: string, message?: string): Promise<void> {
12691330
try {

src/git/gitProvider.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,11 @@ export interface BranchContributorOverview {
120120
export interface GitProviderRepository {
121121
createBranch?(repoPath: string, name: string, ref: string): Promise<void>;
122122
renameBranch?(repoPath: string, oldName: string, newName: string): Promise<void>;
123+
deleteBranch?(
124+
repoPath: string,
125+
branches: GitBranchReference | GitBranchReference[],
126+
options?: { force?: boolean; remote?: boolean },
127+
): Promise<void>;
123128
createTag?(repoPath: string, name: string, ref: string, message?: string): Promise<void>;
124129
deleteTag?(repoPath: string, name: string): Promise<void>;
125130
addRemote?(repoPath: string, name: string, url: string, options?: { fetch?: boolean }): Promise<void>;

src/git/gitProviderService.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1377,6 +1377,25 @@ export class GitProviderService implements Disposable {
13771377
return provider.renameBranch(path, oldName, newName);
13781378
}
13791379

1380+
@log()
1381+
deleteBranch(
1382+
repoPath: string,
1383+
branches: GitBranchReference | GitBranchReference[],
1384+
options?: { force?: boolean; remote?: boolean },
1385+
): Promise<void> {
1386+
const { provider, path } = this.getProvider(repoPath);
1387+
if (provider.deleteBranch == null) throw new ProviderNotSupportedError(provider.descriptor.name);
1388+
1389+
if (!Array.isArray(branches)) {
1390+
branches = [branches];
1391+
}
1392+
1393+
return provider.deleteBranch(path, branches, {
1394+
force: options?.force,
1395+
remote: options?.remote,
1396+
});
1397+
}
1398+
13801399
@log()
13811400
createTag(repoPath: string | Uri, name: string, ref: string, message?: string): Promise<void> {
13821401
const { provider, path } = this.getProvider(repoPath);

src/git/models/repository.ts

Lines changed: 3 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { debug, log, logName } from '../../system/decorators/log';
1515
import { memoize } from '../../system/decorators/memoize';
1616
import type { Deferrable } from '../../system/function';
1717
import { debounce } from '../../system/function';
18-
import { filter, groupByMap, join, map, min, some } from '../../system/iterable';
18+
import { filter, join, map, min, some } from '../../system/iterable';
1919
import { getLoggableName, Logger } from '../../system/logger';
2020
import { getLogScope } from '../../system/logger.scope';
2121
import { updateRecordValue } from '../../system/object';
@@ -26,9 +26,9 @@ import { configuration } from '../../system/vscode/configuration';
2626
import type { GitProviderDescriptor, GitProviderRepository } from '../gitProvider';
2727
import type { GitProviderService } from '../gitProviderService';
2828
import type { GitBranch } from './branch';
29-
import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from './branch';
30-
import type { GitBranchReference, GitReference } from './reference';
29+
import type { GitBranchReference, GitReference, GitTagReference } from './reference';
3130
import { getNameWithoutRemote, isBranchReference } from './reference';
31+
import { getBranchNameWithoutRemote, getRemoteNameFromBranchName } from './branch';
3232
import type { GitRemote } from './remote';
3333
import type { GitWorktree } from './worktree';
3434

@@ -590,49 +590,6 @@ export class Repository implements Disposable {
590590
return remote;
591591
}
592592

593-
@log()
594-
branchDelete(branches: GitBranchReference | GitBranchReference[], options?: { force?: boolean; remote?: boolean }) {
595-
if (!Array.isArray(branches)) {
596-
branches = [branches];
597-
}
598-
599-
const localBranches = branches.filter(b => !b.remote);
600-
if (localBranches.length !== 0) {
601-
const args = ['--delete'];
602-
if (options?.force) {
603-
args.push('--force');
604-
}
605-
void this.runTerminalCommand('branch', ...args, ...branches.map(b => b.ref));
606-
607-
if (options?.remote) {
608-
const trackingBranches = localBranches.filter(b => b.upstream != null);
609-
if (trackingBranches.length !== 0) {
610-
const branchesByOrigin = groupByMap(trackingBranches, b =>
611-
getRemoteNameFromBranchName(b.upstream!.name),
612-
);
613-
614-
for (const [remote, branches] of branchesByOrigin.entries()) {
615-
void this.runTerminalCommand(
616-
'push',
617-
'-d',
618-
remote,
619-
...branches.map(b => getBranchNameWithoutRemote(b.upstream!.name)),
620-
);
621-
}
622-
}
623-
}
624-
}
625-
626-
const remoteBranches = branches.filter(b => b.remote);
627-
if (remoteBranches.length !== 0) {
628-
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));
629-
630-
for (const [remote, branches] of branchesByOrigin.entries()) {
631-
void this.runTerminalCommand('push', '-d', remote, ...branches.map(b => getNameWithoutRemote(b)));
632-
}
633-
}
634-
}
635-
636593
@log()
637594
cherryPick(...args: string[]) {
638595
void this.runTerminalCommand('cherry-pick', ...args);

0 commit comments

Comments
 (0)