Ver código fonte

Adds branch delete option for tracking branches

main
Eric Amodio 4 anos atrás
pai
commit
4e85f47fbe
5 arquivos alterados com 83 adições e 29 exclusões
  1. +45
    -18
      src/commands/git/branch.ts
  2. +1
    -0
      src/commands/git/status.ts
  3. +4
    -0
      src/git/models/branch.ts
  4. +4
    -3
      src/git/models/models.ts
  5. +29
    -8
      src/git/models/repository.ts

+ 45
- 18
src/commands/git/branch.ts Ver arquivo

@ -37,7 +37,7 @@ interface CreateState {
flags: CreateFlags[];
}
type DeleteFlags = '--force';
type DeleteFlags = '--force' | '--remotes';
interface DeleteState {
subcommand: 'delete';
@ -363,7 +363,10 @@ export class BranchGitCommand extends QuickCommand {
state.flags = result;
QuickCommand.endSteps(state);
void state.repo.branchDelete(state.references, { force: state.flags.includes('--force') });
void state.repo.branchDelete(state.references, {
force: state.flags.includes('--force'),
remote: state.flags.includes('--remotes'),
});
}
}
@ -371,24 +374,48 @@ export class BranchGitCommand extends QuickCommand {
state: DeleteStepState<ExcludeSome<DeleteState, 'references', GitBranchReference>>,
context: Context,
): StepResultGenerator<DeleteFlags[]> {
const confirmations: FlagsQuickPickItem<DeleteFlags>[] = [
FlagsQuickPickItem.create<DeleteFlags>(state.flags, [], {
label: context.title,
detail: `Will delete ${GitReference.toString(state.references)}`,
}),
];
if (!state.references.every(b => b.remote)) {
confirmations.push(
FlagsQuickPickItem.create<DeleteFlags>(state.flags, ['--force'], {
label: `Force ${context.title}`,
description: '--force',
detail: `Will forcably delete ${GitReference.toString(state.references)}`,
}),
);
if (state.references.some(b => b.tracking != null)) {
confirmations.push(
FlagsQuickPickItem.create<DeleteFlags>(state.flags, ['--remotes'], {
label: `${context.title} & Remote${
state.references.filter(b => !b.remote).length > 1 ? 's' : ''
}`,
description: '--remotes',
detail: `Will delete ${GitReference.toString(
state.references,
)} and any remote tracking branches`,
}),
FlagsQuickPickItem.create<DeleteFlags>(state.flags, ['--force', '--remotes'], {
label: `Force ${context.title} & Remote${
state.references.filter(b => !b.remote).length > 1 ? 's' : ''
}`,
description: '--force --remotes',
detail: `Will forcably delete ${GitReference.toString(
state.references,
)} and any remote tracking branches`,
}),
);
}
}
const step: QuickPickStep<FlagsQuickPickItem<DeleteFlags>> = QuickCommand.createConfirmStep(
appendReposToTitle(`Confirm ${context.title}`, state, context),
[
FlagsQuickPickItem.create<DeleteFlags>(state.flags, [], {
label: context.title,
detail: `Will delete ${GitReference.toString(state.references)}`,
}),
// Don't allow force if there are remote branches
...(!state.references.some(r => r.remote)
? [
FlagsQuickPickItem.create<DeleteFlags>(state.flags, ['--force'], {
label: `Force ${context.title}`,
description: '--force',
detail: `Will forcably delete ${GitReference.toString(state.references)}`,
}),
]
: []),
],
confirmations,
context,
);
const selection: StepSelection<typeof step> = yield step;

+ 1
- 0
src/commands/git/status.ts Ver arquivo

@ -89,6 +89,7 @@ export class StatusGitCommand extends QuickCommand {
refType: 'branch',
name: context.status.branch,
remote: false,
tracking: context.status.upstream,
}),
{ icon: false },
)}`;

+ 4
- 0
src/git/models/branch.ts Ver arquivo

@ -219,6 +219,10 @@ export class GitBranch implements GitBranchReference {
return `(${GitRevision.shorten(sha)}...)`;
}
static getNameWithoutRemote(name: string): string {
return name.substring(name.indexOf('/') + 1);
}
static getRemote(name: string): string {
return name.substring(0, name.indexOf('/'));
}

+ 4
- 3
src/git/models/models.ts Ver arquivo

@ -1,5 +1,5 @@
'use strict';
import { GitBranch } from './branch';
import { Container } from '../../container';
import { GlyphChars } from '../../constants';
@ -97,6 +97,7 @@ export interface GitBranchReference {
name: string;
ref: string;
readonly remote: boolean;
readonly tracking?: string;
repoPath: string;
}
@ -133,7 +134,7 @@ export namespace GitReference {
export function create(
ref: string,
repoPath: string,
options: { refType: 'branch'; name: string; remote: boolean },
options: { refType: 'branch'; name: string; remote: boolean; tracking?: string },
): GitBranchReference;
export function create(
ref: string,
@ -194,7 +195,7 @@ export namespace GitReference {
export function getNameWithoutRemote(ref: GitReference) {
if (ref.refType === 'branch') {
return ref.remote ? ref.name.substring(ref.name.indexOf('/') + 1) : ref.name;
return ref.remote ? GitBranch.getNameWithoutRemote(ref.name) : ref.name;
}
return ref.name;
}

+ 29
- 8
src/git/models/repository.ts Ver arquivo

@ -16,15 +16,15 @@ import {
import { configuration } from '../../configuration';
import { StarredRepositories, WorkspaceState } from '../../constants';
import { Container } from '../../container';
import { Functions, gate, Iterables, log, logName } from '../../system';
import { GitBranch, GitContributor, GitDiffShortStat, GitRemote, GitStash, GitStatus, GitTag } from '../git';
import { GitService } from '../gitService';
import { GitUri } from '../gitUri';
import { RemoteProviderFactory, RemoteProviders, RemoteProviderWithApi } from '../remotes/factory';
import { Messages } from '../../messages';
import { Logger } from '../../logger';
import { runGitCommandInTerminal } from '../../terminal';
import { Messages } from '../../messages';
import { GitBranchReference, GitReference, GitTagReference } from './models';
import { RemoteProviderFactory, RemoteProviders, RemoteProviderWithApi } from '../remotes/factory';
import { Arrays, Functions, gate, Iterables, log, logName } from '../../system';
import { runGitCommandInTerminal } from '../../terminal';
const ignoreGitRegex = /\.git(?:\/|\\|$)/;
const refsRegex = /\.git\/refs\/(heads|remotes|tags)/;
@ -275,7 +275,10 @@ export class Repository implements Disposable {
@gate()
@log()
branchDelete(branches: GitBranchReference | GitBranchReference[], { force }: { force?: boolean } = {}) {
branchDelete(
branches: GitBranchReference | GitBranchReference[],
{ force, remote }: { force?: boolean; remote?: boolean } = {},
) {
if (!Array.isArray(branches)) {
branches = [branches];
}
@ -287,16 +290,34 @@ export class Repository implements Disposable {
args.push('--force');
}
this.runTerminalCommand('branch', ...args, ...branches.map(b => b.ref));
if (remote) {
const trackingBranches = localBranches.filter(b => b.tracking != null);
if (trackingBranches.length !== 0) {
const branchesByOrigin = Arrays.groupByMap(trackingBranches, b => GitBranch.getRemote(b.tracking!));
for (const [remote, branches] of branchesByOrigin.entries()) {
this.runTerminalCommand(
'push',
'-d',
remote,
...branches.map(b => GitBranch.getNameWithoutRemote(b.tracking!)),
);
}
}
}
}
const remoteBranches = branches.filter(b => b.remote);
if (remoteBranches.length !== 0) {
for (const branch of remoteBranches) {
const branchesByOrigin = Arrays.groupByMap(remoteBranches, b => GitBranch.getRemote(b.name));
for (const [remote, branches] of branchesByOrigin.entries()) {
this.runTerminalCommand(
'push',
'-d',
GitBranch.getRemote(branch.name),
GitReference.getNameWithoutRemote(branch),
remote,
...branches.map(b => GitReference.getNameWithoutRemote(b)),
);
}
}

Carregando…
Cancelar
Salvar