Skip to content

Commit 275d1f4

Browse files
committed
add branchDelete
1 parent 8b2779d commit 275d1f4

File tree

6 files changed

+108
-60
lines changed

6 files changed

+108
-60
lines changed

src/commands/git/branch.ts

+2-1
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,8 @@ export class BranchGitCommand extends QuickCommand {
508508
state.flags = result;
509509

510510
endSteps(state);
511-
state.repo.branchDelete(state.references, {
511+
512+
await state.repo.git.branchDelete(state.references, {
512513
force: state.flags.includes('--force'),
513514
remote: state.flags.includes('--remotes'),
514515
});

src/env/node/git/git.ts

+22-12
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ import {
2727
import type { GitDir } from '../../../git/gitProvider';
2828
import type { GitDiffFilter } from '../../../git/models/diff';
2929
import type { GitRevisionRange } from '../../../git/models/reference';
30-
import { isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/models/reference';
30+
import { GitBranchReference, isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/models/reference';
3131
import type { GitUser } from '../../../git/models/user';
3232
import { parseGitBranchesDefaultFormat } from '../../../git/parsers/branchParser';
3333
import { parseGitLogAllFormat, parseGitLogDefaultFormat } from '../../../git/parsers/logParser';
@@ -506,7 +506,7 @@ export class Git {
506506
}
507507
}
508508

509-
branch(repoPath: string, ...args: string[]) {
509+
async branch(repoPath: string, ...args: string[]): Promise<void> {
510510
return this.git<string>({ cwd: repoPath }, 'branch', ...args);
511511
}
512512

@@ -962,6 +962,10 @@ export class Git {
962962
publish?: boolean;
963963
remote?: string;
964964
upstream?: string;
965+
delete?: {
966+
remote: string;
967+
branches: string[];
968+
};
965969
},
966970
): Promise<void> {
967971
const params = ['push'];
@@ -979,16 +983,22 @@ export class Git {
979983
}
980984
}
981985

982-
if (options.branch && options.remote) {
983-
if (options.upstream) {
984-
params.push('-u', options.remote, `${options.branch}:${options.upstream}`);
985-
} else if (options.publish) {
986-
params.push('--set-upstream', options.remote, options.branch);
987-
} else {
988-
params.push(options.remote, options.branch);
989-
}
990-
} else if (options.remote) {
991-
params.push(options.remote);
986+
switch (true) {
987+
case options.branch && options.remote:
988+
if (options.upstream) {
989+
params.push('-u', options.remote, `${options.branch}:${options.upstream}`);
990+
} else if (options.publish) {
991+
params.push('--set-upstream', options.remote, options.branch);
992+
} else {
993+
params.push(options.remote, options.branch);
994+
}
995+
break;
996+
case options.remote:
997+
params.push(options.remote);
998+
break;
999+
case options.delete:
1000+
params.push('-d', options.delete.remote, ...options.delete.branches);
1001+
break;
9921002
}
9931003

9941004
try {

src/env/node/git/localGitProvider.ts

+51-2
Original file line numberDiff line numberDiff line change
@@ -1234,11 +1234,60 @@ export class LocalGitProvider implements GitProvider, Disposable {
12341234
@log()
12351235
async branch(repoPath: string, options: GitBranchOptions): Promise<void> {
12361236
if (options?.create != null) {
1237-
return this.git.branch(repoPath, options.create.name, options.create.startRef);
1237+
const { name, startRef } = options.create;
1238+
return this.git.branch(repoPath, name, startRef);
12381239
}
12391240

12401241
if (options?.rename != null) {
1241-
return this.git.branch(repoPath, '-m', options.rename.old, options.rename.new);
1242+
const { old: oldName, new: newName } = options.rename;
1243+
return this.git.branch(repoPath, '-m', oldName, newName);
1244+
}
1245+
1246+
if (options?.delete != null) {
1247+
const { force: forceOpt = false, remote: remoteOpt = false, branches } = options.delete;
1248+
const localBranches = branches.filter((b: GitBranchReference) => !b.remote);
1249+
if (localBranches.length !== 0) {
1250+
const args = ['--delete'];
1251+
if (forceOpt) {
1252+
args.push('--force');
1253+
}
1254+
1255+
void this.git.branch(repoPath, ...args, ...branches.map((b: GitBranchReference) => b.ref));
1256+
1257+
if (remoteOpt) {
1258+
const trackingBranches = localBranches.filter(b => b.upstream != null);
1259+
if (trackingBranches.length !== 0) {
1260+
const branchesByOrigin = groupByMap(trackingBranches, b =>
1261+
getRemoteNameFromBranchName(b.upstream!.name),
1262+
);
1263+
1264+
for (const [remote, branches] of branchesByOrigin.entries()) {
1265+
void this.git.push(repoPath, {
1266+
delete: {
1267+
remote: remote,
1268+
branches: branches.map(b => getBranchNameWithoutRemote(b.upstream!.name)),
1269+
},
1270+
});
1271+
}
1272+
}
1273+
}
1274+
}
1275+
1276+
const remoteBranches = branches.filter((b: GitBranchReference) => b.remote);
1277+
if (remoteBranches.length !== 0) {
1278+
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));
1279+
1280+
for (const [remote, branches] of branchesByOrigin.entries()) {
1281+
void this.git.push(repoPath, {
1282+
delete: {
1283+
remote: remote,
1284+
branches: branches.map((b: GitBranchReference) =>
1285+
b.remote ? getBranchNameWithoutRemote(b.name) : b.name,
1286+
),
1287+
},
1288+
});
1289+
}
1290+
}
12421291
}
12431292

12441293
throw new Error('Invalid branch options');

src/git/gitProvider.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ export type GitBranchOptions = {
121121
name: string;
122122
startRef: string;
123123
};
124+
delete?: {
125+
force?: boolean;
126+
remote?: boolean;
127+
branches: GitBranchReference[];
128+
};
124129
};
125130

126131
export interface GitProviderRepository {
@@ -489,7 +494,7 @@ export interface GitProvider extends GitProviderRepository, Disposable {
489494
getWorkingUri(repoPath: string, uri: Uri): Promise<Uri | undefined>;
490495

491496
applyChangesToWorkingFile(uri: GitUri, ref1?: string, ref2?: string): Promise<void>;
492-
branch(_repoPath: string, _options: GitBranchOptions): Promise<void>;
497+
branch(repoPath: string, options: GitBranchOptions): Promise<void>;
493498
clone?(url: string, parentPath: string): Promise<string | undefined>;
494499
/**
495500
* Returns the blame of a file

src/git/gitProviderService.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ import { configuration } from '../system/vscode/configuration';
4444
import { setContext } from '../system/vscode/context';
4545
import { getBestPath } from '../system/vscode/path';
4646
import type {
47-
GitBranchOptions,
4847
GitCaches,
4948
GitDir,
5049
GitProvider,
@@ -1359,6 +1358,32 @@ export class GitProviderService implements Disposable {
13591358
}
13601359
}
13611360

1361+
@log()
1362+
branchDelete(
1363+
repoPath: string,
1364+
branches: GitBranchReference | GitBranchReference[],
1365+
options?: { force?: boolean; remote?: boolean },
1366+
): Promise<void> {
1367+
const { provider, path } = this.getProvider(repoPath);
1368+
1369+
if (!Array.isArray(branches)) {
1370+
branches = [branches];
1371+
}
1372+
1373+
try {
1374+
return provider.branch(path, {
1375+
delete: {
1376+
force: options?.force,
1377+
remote: options?.remote,
1378+
branches: branches,
1379+
},
1380+
});
1381+
} catch (ex) {
1382+
Logger.error(ex);
1383+
return showGenericErrorMessage('Unable to delete branch');
1384+
}
1385+
}
1386+
13621387
@log()
13631388
checkout(
13641389
repoPath: string | Uri,

src/git/models/repository.ts

+1-43
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ export type RepoGitProviderService = Pick<
4141
| keyof GitProviderRepository
4242
| 'branchCreate'
4343
| 'branchRename'
44+
| 'branchDelete'
4445
| 'getBestRemoteWithIntegration'
4546
| 'getBranch'
4647
| 'getRemote'
@@ -562,49 +563,6 @@ export class Repository implements Disposable {
562563
return remote;
563564
}
564565

565-
@log()
566-
branchDelete(branches: GitBranchReference | GitBranchReference[], options?: { force?: boolean; remote?: boolean }) {
567-
if (!Array.isArray(branches)) {
568-
branches = [branches];
569-
}
570-
571-
const localBranches = branches.filter(b => !b.remote);
572-
if (localBranches.length !== 0) {
573-
const args = ['--delete'];
574-
if (options?.force) {
575-
args.push('--force');
576-
}
577-
void this.runTerminalCommand('branch', ...args, ...branches.map(b => b.ref));
578-
579-
if (options?.remote) {
580-
const trackingBranches = localBranches.filter(b => b.upstream != null);
581-
if (trackingBranches.length !== 0) {
582-
const branchesByOrigin = groupByMap(trackingBranches, b =>
583-
getRemoteNameFromBranchName(b.upstream!.name),
584-
);
585-
586-
for (const [remote, branches] of branchesByOrigin.entries()) {
587-
void this.runTerminalCommand(
588-
'push',
589-
'-d',
590-
remote,
591-
...branches.map(b => getBranchNameWithoutRemote(b.upstream!.name)),
592-
);
593-
}
594-
}
595-
}
596-
}
597-
598-
const remoteBranches = branches.filter(b => b.remote);
599-
if (remoteBranches.length !== 0) {
600-
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));
601-
602-
for (const [remote, branches] of branchesByOrigin.entries()) {
603-
void this.runTerminalCommand('push', '-d', remote, ...branches.map(b => getNameWithoutRemote(b)));
604-
}
605-
}
606-
}
607-
608566
@log()
609567
cherryPick(...args: string[]) {
610568
void this.runTerminalCommand('cherry-pick', ...args);

0 commit comments

Comments
 (0)