提交 9a332140 编写于 作者: J Joao Moreno

git: undo command

上级 7c2ea174
......@@ -247,7 +247,7 @@
{
"command": "git.undoCommit",
"group": "3_commit",
"when": "scmProvider == none"
"when": "scmProvider == git"
},
{
"command": "git.unstageAll",
......
......@@ -6,7 +6,7 @@
'use strict';
import { Uri, commands, scm, Disposable, SCMResourceGroup, SCMResource, window, workspace, QuickPickItem, OutputChannel } from 'vscode';
import { IRef, RefType } from './git';
import { Ref, RefType } from './git';
import { Model, Resource, Status, CommitOptions } from './model';
import * as path from 'path';
import * as nls from 'vscode-nls';
......@@ -38,7 +38,7 @@ class CheckoutItem implements QuickPickItem {
get label(): string { return this.ref.name || this.shortCommit; }
get description(): string { return this.shortCommit; }
constructor(protected ref: IRef) { }
constructor(protected ref: Ref) { }
async run(model: Model): Promise<void> {
const ref = this.treeish;
......@@ -415,7 +415,15 @@ export class CommandCenter {
@CommandCenter.Command('git.undoCommit')
@CommandCenter.CatchErrors
async undoCommit(): Promise<void> {
await Promise.reject('not implemented');
const HEAD = this.model.HEAD;
if (!HEAD || !HEAD.commit) {
return;
}
const commit = await this.model.getCommit('HEAD');
await this.model.reset('HEAD~');
scm.inputBox.value = commit.message;
}
@CommandCenter.Command('git.checkout')
......
......@@ -22,7 +22,7 @@ export interface IGit {
version: string;
}
export interface IPushOptions {
export interface PushOptions {
setUpstream?: boolean;
}
......@@ -33,7 +33,7 @@ export interface IFileStatus {
rename?: string;
}
export interface IRemote {
export interface Remote {
name: string;
url: string;
}
......@@ -44,14 +44,14 @@ export enum RefType {
Tag
}
export interface IRef {
export interface Ref {
type: RefType;
name?: string;
commit?: string;
remote?: string;
}
export interface IBranch extends IRef {
export interface Branch extends Ref {
upstream?: string;
ahead?: number;
behind?: number;
......@@ -371,7 +371,7 @@ export class Git {
}
}
export interface ICommit {
export interface Commit {
hash: string;
message: string;
}
......@@ -676,7 +676,7 @@ export class Repository {
}
}
async push(remote?: string, name?: string, options?: IPushOptions): Promise<void> {
async push(remote?: string, name?: string, options?: PushOptions): Promise<void> {
const args = ['push'];
if (options && options.setUpstream) {
......@@ -754,7 +754,7 @@ export class Repository {
return result;
}
async getHEAD(): Promise<IRef> {
async getHEAD(): Promise<Ref> {
try {
const result = await this.run(['symbolic-ref', '--short', 'HEAD']);
......@@ -774,10 +774,10 @@ export class Repository {
}
}
async getRefs(): Promise<IRef[]> {
async getRefs(): Promise<Ref[]> {
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)']);
const fn = (line): IRef | null => {
const fn = (line): Ref | null => {
let match: RegExpExecArray | null;
if (match = /^refs\/heads\/([^ ]+) ([0-9a-f]{40})$/.exec(line)) {
......@@ -794,10 +794,10 @@ export class Repository {
return result.stdout.trim().split('\n')
.filter(line => !!line)
.map(fn)
.filter(ref => !!ref) as IRef[];
.filter(ref => !!ref) as Ref[];
}
async getRemotes(): Promise<IRemote[]> {
async getRemotes(): Promise<Remote[]> {
const result = await this.run(['remote', '--verbose']);
const regex = /^([^\s]+)\s+([^\s]+)\s/;
const rawRemotes = result.stdout.trim().split('\n')
......@@ -809,7 +809,7 @@ export class Repository {
return uniqBy(rawRemotes, remote => remote.name);
}
async getBranch(name: string): Promise<IBranch> {
async getBranch(name: string): Promise<Branch> {
if (name === 'HEAD') {
return this.getHEAD();
}
......@@ -817,7 +817,7 @@ export class Repository {
const result = await this.run(['rev-parse', name]);
if (!result.stdout) {
return Promise.reject<IBranch>(new Error('No such branch'));
return Promise.reject<Branch>(new Error('No such branch'));
}
const commit = result.stdout.trim();
......@@ -872,12 +872,12 @@ export class Repository {
}
}
async getCommit(ref: string): Promise<ICommit> {
async getCommit(ref: string): Promise<Commit> {
const result = await this.run(['show', '-s', '--format=%H\n%B', ref]);
const match = /^([0-9a-f]{40})\n([^]*)$/m.exec(result.stdout.trim());
if (!match) {
return Promise.reject<ICommit>('bad commit format');
return Promise.reject<Commit>('bad commit format');
}
return { hash: match[1], message: match[2] };
......
......@@ -6,7 +6,7 @@
'use strict';
import { Uri, EventEmitter, Event, SCMResource, SCMResourceDecorations, SCMResourceGroup, Disposable, window, workspace } from 'vscode';
import { Repository, IRef, IBranch, IRemote, IPushOptions } from './git';
import { Repository, Ref, Branch, Remote, PushOptions, Commit } from './git';
import { anyEvent, eventToPromise, filterEvent, mapEvent } from './util';
import { memoize, throttle, debounce } from './decorators';
import { watch } from './watch';
......@@ -161,10 +161,11 @@ export enum Operation {
Clean = 1 << 4,
Branch = 1 << 5,
Checkout = 1 << 6,
Fetch = 1 << 7,
Pull = 1 << 8,
Push = 1 << 9,
Sync = 1 << 10
Reset = 1 << 7,
Fetch = 1 << 8,
Pull = 1 << 9,
Push = 1 << 10,
Sync = 1 << 11,
}
export interface Operations {
......@@ -274,18 +275,18 @@ export class Model {
return this._repositoryRoot;
}
private _HEAD: IBranch | undefined;
get HEAD(): IBranch | undefined {
private _HEAD: Branch | undefined;
get HEAD(): Branch | undefined {
return this._HEAD;
}
private _refs: IRef[] = [];
get refs(): IRef[] {
private _refs: Ref[] = [];
get refs(): Ref[] {
return this._refs;
}
private _remotes: IRemote[] = [];
get remotes(): IRemote[] {
private _remotes: Remote[] = [];
get remotes(): Remote[] {
return this._remotes;
}
......@@ -358,6 +359,16 @@ export class Model {
await this.run(Operation.Checkout, () => this.repository.checkout(treeish, []));
}
@throttle
async getCommit(ref: string): Promise<Commit> {
return await this.repository.getCommit(ref);
}
@throttle
async reset(treeish: string, hard?: boolean): Promise<void> {
await this.run(Operation.Reset, () => this.repository.reset(treeish, hard));
}
@throttle
async fetch(): Promise<void> {
await this.run(Operation.Fetch, () => this.repository.fetch());
......@@ -369,7 +380,7 @@ export class Model {
}
@throttle
async push(remote?: string, name?: string, options?: IPushOptions): Promise<void> {
async push(remote?: string, name?: string, options?: PushOptions): Promise<void> {
await this.run(Operation.Push, () => this.repository.push(remote, name, options));
}
......@@ -396,7 +407,7 @@ export class Model {
@throttle
private async update(): Promise<void> {
const status = await this.repository.getStatus();
let HEAD: IBranch | undefined;
let HEAD: Branch | undefined;
try {
HEAD = await this.repository.getHEAD();
......
......@@ -6,7 +6,7 @@
'use strict';
import { window, Disposable, StatusBarItem, StatusBarAlignment } from 'vscode';
import { RefType, IBranch } from './git';
import { RefType, Branch } from './git';
import { Model, Operation } from './model';
import * as nls from 'vscode-nls';
......@@ -58,7 +58,7 @@ export class CheckoutStatusBar {
interface SyncStatusBarState {
isSyncRunning: boolean;
hasRemotes: boolean;
HEAD: IBranch | undefined;
HEAD: Branch | undefined;
}
export class SyncStatusBar {
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册