Skip to content

Commit

Permalink
Adds reset git command
Browse files Browse the repository at this point in the history
  • Loading branch information
eamodio committed Sep 3, 2019
1 parent e9cb81c commit fdc1389
Show file tree
Hide file tree
Showing 2 changed files with 178 additions and 0 deletions.
175 changes: 175 additions & 0 deletions src/commands/git/reset.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,175 @@
'use strict';
/* eslint-disable no-loop-func */
import { Container } from '../../container';
import { GitReference, Repository } from '../../git/gitService';
import { GlyphChars } from '../../constants';
import { Iterables, Strings } from '../../system';
import { QuickCommandBase, StepAsyncGenerator, StepSelection, StepState } from '../quickCommand';
import {
CommitQuickPickItem,
Directive,
DirectiveQuickPickItem,
GitFlagsQuickPickItem,
RepositoryQuickPickItem
} from '../../quickpicks';
import { runGitCommandInTerminal } from '../../terminal';
import { Logger } from '../../logger';

interface State {
repo: Repository;
reference?: GitReference;
flags: string[];
}

export interface ResetGitCommandArgs {
readonly command: 'reset';
state?: Partial<State>;
}

export class ResetGitCommand extends QuickCommandBase<State> {
constructor(args?: ResetGitCommandArgs) {
super('reset', 'reset', 'Reset', false, { description: 'via Terminal' });

if (args === undefined || args.state === undefined) return;

let counter = 0;
if (args.state.repo !== undefined) {
counter++;
}

if (args.state.reference !== undefined) {
counter++;
}

this._initialState = {
counter: counter,
confirm: true,
...args.state
};
}

execute(state: State) {
runGitCommandInTerminal('reset', [...state.flags, state.reference!.ref].join(' '), state.repo.path, true);
}

protected async *steps(): StepAsyncGenerator {
const state: StepState<State> = this._initialState === undefined ? { counter: 0 } : this._initialState;
let oneRepo = false;

while (true) {
try {
if (state.repo === undefined || state.counter < 1) {
const repos = [...(await Container.git.getOrderedRepositories())];

if (repos.length === 1) {
oneRepo = true;
state.counter++;
state.repo = repos[0];
} else {
const active = state.repo ? state.repo : await Container.git.getActiveRepository();

const step = this.createPickStep<RepositoryQuickPickItem>({
title: this.title,
placeholder: 'Choose a repository',
items: await Promise.all(
repos.map(r =>
RepositoryQuickPickItem.create(r, r.id === (active && active.id), {
branch: true,
fetched: true,
status: true
})
)
)
});
const selection: StepSelection<typeof step> = yield step;

if (!this.canPickStepMoveNext(step, state, selection)) {
break;
}

state.repo = selection[0].item;
}
}

const destination = await state.repo.getBranch();
if (destination === undefined) break;

if (state.reference === undefined || state.counter < 2) {
const log = await Container.git.getLog(state.repo.path, {
ref: destination.ref,
merges: false
});

const step = this.createPickStep<CommitQuickPickItem>({
title: `${this.title} ${destination.name}${Strings.pad(GlyphChars.Dot, 2, 2)}${
state.repo.formattedName
}`,
placeholder:
log === undefined ? `${destination.name} has no commits` : 'Choose commit to reset to',
matchOnDescription: true,
matchOnDetail: true,
items:
log === undefined
? [
DirectiveQuickPickItem.create(Directive.Back, true),
DirectiveQuickPickItem.create(Directive.Cancel)
]
: [
...Iterables.map(log.commits.values(), commit =>
CommitQuickPickItem.create(
commit,
state.reference ? state.reference.ref === commit.ref : undefined,
{ compact: true, icon: true }
)
)
]
});
const selection: StepSelection<typeof step> = yield step;

if (!this.canPickStepMoveNext(step, state, selection)) {
if (oneRepo) {
break;
}
continue;
}

state.reference = selection[0].item;
}

const step = this.createConfirmStep<GitFlagsQuickPickItem>(
`Confirm ${this.title}${Strings.pad(GlyphChars.Dot, 2, 2)}${state.repo.formattedName}`,
[
{
label: `Soft ${this.title}`,
description: `--soft ${destination.name} to ${state.reference.name}`,
detail: `Will soft reset (leaves changes in the working tree) ${destination.name} to ${state.reference.name}`,
item: ['--soft']
},
{
label: `Hard ${this.title}`,
description: `--hard ${destination.name} to ${state.reference.name}`,
detail: `Will hard reset (discards all changes) ${destination.name} to ${state.reference.name}`,
item: ['--hard']
}
]
);
const selection: StepSelection<typeof step> = yield step;

if (!this.canPickStepMoveNext(step, state, selection)) {
continue;
}

state.flags = selection[0].item;

this.execute(state as State);
break;
} catch (ex) {
Logger.error(ex, this.title);

throw ex;
}
}

return undefined;
}
}
3 changes: 3 additions & 0 deletions src/commands/gitCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { MergeGitCommand, MergeGitCommandArgs } from './git/merge';
import { PullGitCommand, PullGitCommandArgs } from './git/pull';
import { PushGitCommand, PushGitCommandArgs } from './git/push';
import { RebaseGitCommand, RebaseGitCommandArgs } from './git/rebase';
import { ResetGitCommand, ResetGitCommandArgs } from './git/reset';
import { StashGitCommand, StashGitCommandArgs } from './git/stash';
import { SwitchGitCommand, SwitchGitCommandArgs } from './git/switch';
import { Container } from '../container';
Expand All @@ -31,6 +32,7 @@ export type GitCommandsCommandArgs =
| PullGitCommandArgs
| PushGitCommandArgs
| RebaseGitCommandArgs
| ResetGitCommandArgs
| StashGitCommandArgs
| SwitchGitCommandArgs;

Expand All @@ -48,6 +50,7 @@ class PickCommandStep implements QuickPickStep {
new PullGitCommand(args && args.command === 'pull' ? args : undefined),
new PushGitCommand(args && args.command === 'push' ? args : undefined),
new RebaseGitCommand(args && args.command === 'rebase' ? args : undefined),
new ResetGitCommand(args && args.command === 'reset' ? args : undefined),
new StashGitCommand(args && args.command === 'stash' ? args : undefined),
new SwitchGitCommand(args && args.command === 'switch' ? args : undefined)
];
Expand Down

0 comments on commit fdc1389

Please sign in to comment.