Skip to content

Commit

Permalink
add branchDelete
Browse files Browse the repository at this point in the history
  • Loading branch information
sergiolms committed Sep 26, 2024
1 parent 8b2779d commit d2ada6c
Show file tree
Hide file tree
Showing 6 changed files with 103 additions and 60 deletions.
3 changes: 2 additions & 1 deletion src/commands/git/branch.ts
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,8 @@ export class BranchGitCommand extends QuickCommand {
state.flags = result;

endSteps(state);
state.repo.branchDelete(state.references, {

await state.repo.git.branchDelete(state.references, {
force: state.flags.includes('--force'),
remote: state.flags.includes('--remotes'),
});
Expand Down
34 changes: 22 additions & 12 deletions src/env/node/git/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ import {
import type { GitDir } from '../../../git/gitProvider';
import type { GitDiffFilter } from '../../../git/models/diff';
import type { GitRevisionRange } from '../../../git/models/reference';
import { isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/models/reference';
import { GitBranchReference, isUncommitted, isUncommittedStaged, shortenRevision } from '../../../git/models/reference';
import type { GitUser } from '../../../git/models/user';
import { parseGitBranchesDefaultFormat } from '../../../git/parsers/branchParser';
import { parseGitLogAllFormat, parseGitLogDefaultFormat } from '../../../git/parsers/logParser';
Expand Down Expand Up @@ -506,7 +506,7 @@ export class Git {
}
}

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

Expand Down Expand Up @@ -962,6 +962,10 @@ export class Git {
publish?: boolean;
remote?: string;
upstream?: string;
delete?: {
remote: string;
branches: string[];
};
},
): Promise<void> {
const params = ['push'];
Expand All @@ -979,16 +983,22 @@ export class Git {
}
}

if (options.branch && options.remote) {
if (options.upstream) {
params.push('-u', options.remote, `${options.branch}:${options.upstream}`);
} else if (options.publish) {
params.push('--set-upstream', options.remote, options.branch);
} else {
params.push(options.remote, options.branch);
}
} else if (options.remote) {
params.push(options.remote);
switch (true) {
case options.branch && options.remote:
if (options.upstream) {
params.push('-u', options.remote, `${options.branch}:${options.upstream}`);
} else if (options.publish) {
params.push('--set-upstream', options.remote, options.branch);
} else {
params.push(options.remote, options.branch);
}
break;
case options.remote:
params.push(options.remote);
break;
case options.delete:
params.push('-d', options.delete.remote, ...options.delete.branches);
break;
}

try {
Expand Down
53 changes: 51 additions & 2 deletions src/env/node/git/localGitProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1234,11 +1234,60 @@ export class LocalGitProvider implements GitProvider, Disposable {
@log()
async branch(repoPath: string, options: GitBranchOptions): Promise<void> {
if (options?.create != null) {
return this.git.branch(repoPath, options.create.name, options.create.startRef);
const { name, startRef } = options.create;
return this.git.branch(repoPath, name, startRef);
}

if (options?.rename != null) {
return this.git.branch(repoPath, '-m', options.rename.old, options.rename.new);
const { old: oldName, new: newName } = options.rename;
return this.git.branch(repoPath, '-m', oldName, newName);
}

if (options?.delete != null) {
const { force: forceOpt = false, remote: remoteOpt = false, branches } = options.delete;
const localBranches = branches.filter((b: GitBranchReference) => !b.remote);
if (localBranches.length !== 0) {
const args = ['--delete'];
if (forceOpt) {
args.push('--force');
}

void this.git.branch(repoPath, ...args, ...branches.map((b: GitBranchReference) => b.ref));

if (remoteOpt) {
const trackingBranches = localBranches.filter(b => b.upstream != null);
if (trackingBranches.length !== 0) {
const branchesByOrigin = groupByMap(trackingBranches, b =>
getRemoteNameFromBranchName(b.upstream!.name),
);

for (const [remote, branches] of branchesByOrigin.entries()) {
void this.git.push(repoPath, {
delete: {
remote: remote,
branches: branches.map(b => getBranchNameWithoutRemote(b.upstream!.name)),
},
});
}
}
}
}

const remoteBranches = branches.filter((b: GitBranchReference) => b.remote);
if (remoteBranches.length !== 0) {
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));

for (const [remote, branches] of branchesByOrigin.entries()) {
void this.git.push(repoPath, {
delete: {
remote: remote,
branches: branches.map((b: GitBranchReference) =>
b.remote ? getBranchNameWithoutRemote(b.name) : b.name,
),
},
});
}
}
}

throw new Error('Invalid branch options');
Expand Down
2 changes: 1 addition & 1 deletion src/git/gitProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -489,7 +489,7 @@ export interface GitProvider extends GitProviderRepository, Disposable {
getWorkingUri(repoPath: string, uri: Uri): Promise<Uri | undefined>;

applyChangesToWorkingFile(uri: GitUri, ref1?: string, ref2?: string): Promise<void>;
branch(_repoPath: string, _options: GitBranchOptions): Promise<void>;
branch(repoPath: string, options: GitBranchOptions): Promise<void>;
clone?(url: string, parentPath: string): Promise<string | undefined>;
/**
* Returns the blame of a file
Expand Down
27 changes: 26 additions & 1 deletion src/git/gitProviderService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,6 @@ import { configuration } from '../system/vscode/configuration';
import { setContext } from '../system/vscode/context';
import { getBestPath } from '../system/vscode/path';
import type {
GitBranchOptions,
GitCaches,
GitDir,
GitProvider,
Expand Down Expand Up @@ -1359,6 +1358,32 @@ export class GitProviderService implements Disposable {
}
}

@log()
branchDelete(
repoPath: string,
branches: GitBranchReference | GitBranchReference[],
options?: { force?: boolean; remote?: boolean },
): Promise<void> {
const { provider, path } = this.getProvider(repoPath);

if (!Array.isArray(branches)) {
branches = [branches];
}

try {
return provider.branch(path, {
delete: {
force: options?.force,
remote: options?.remote,
branches: branches,
},
});
} catch (ex) {
Logger.error(ex);
return showGenericErrorMessage('Unable to delete branch');
}
}

@log()
checkout(
repoPath: string | Uri,
Expand Down
44 changes: 1 addition & 43 deletions src/git/models/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type RepoGitProviderService = Pick<
| keyof GitProviderRepository
| 'branchCreate'
| 'branchRename'
| 'branchDelete'
| 'getBestRemoteWithIntegration'
| 'getBranch'
| 'getRemote'
Expand Down Expand Up @@ -562,49 +563,6 @@ export class Repository implements Disposable {
return remote;
}

@log()
branchDelete(branches: GitBranchReference | GitBranchReference[], options?: { force?: boolean; remote?: boolean }) {
if (!Array.isArray(branches)) {
branches = [branches];
}

const localBranches = branches.filter(b => !b.remote);
if (localBranches.length !== 0) {
const args = ['--delete'];
if (options?.force) {
args.push('--force');
}
void this.runTerminalCommand('branch', ...args, ...branches.map(b => b.ref));

if (options?.remote) {
const trackingBranches = localBranches.filter(b => b.upstream != null);
if (trackingBranches.length !== 0) {
const branchesByOrigin = groupByMap(trackingBranches, b =>
getRemoteNameFromBranchName(b.upstream!.name),
);

for (const [remote, branches] of branchesByOrigin.entries()) {
void this.runTerminalCommand(
'push',
'-d',
remote,
...branches.map(b => getBranchNameWithoutRemote(b.upstream!.name)),
);
}
}
}
}

const remoteBranches = branches.filter(b => b.remote);
if (remoteBranches.length !== 0) {
const branchesByOrigin = groupByMap(remoteBranches, b => getRemoteNameFromBranchName(b.name));

for (const [remote, branches] of branchesByOrigin.entries()) {
void this.runTerminalCommand('push', '-d', remote, ...branches.map(b => getNameWithoutRemote(b)));
}
}
}

@log()
cherryPick(...args: string[]) {
void this.runTerminalCommand('cherry-pick', ...args);
Expand Down

0 comments on commit d2ada6c

Please sign in to comment.