Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion src/vs/workbench/parts/git/browser/gitActions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ import { IGitService, IFileStatus, Status, StatusType, ServiceState,
import { IQuickOpenService } from 'vs/workbench/services/quickopen/common/quickOpenService';
import paths = require('vs/base/common/paths');
import URI from 'vs/base/common/uri';
import { IStorageService } from 'vs/platform/storage/common/storage';

function flatten(context?: any, preferFocus = false): IFileStatus[] {
if (!context) {
Expand Down Expand Up @@ -1176,13 +1177,16 @@ export class UndoLastCommitAction extends GitAction {

static ID = 'workbench.action.git.undoLastCommit';
static LABEL = nls.localize('undoLastCommit', "Undo Last Commit");
private storageService: IStorageService;

constructor(
id = UndoLastCommitAction.ID,
label = UndoLastCommitAction.LABEL,
@IGitService gitService: IGitService
@IGitService gitService: IGitService,
@IStorageService storageService: IStorageService
) {
super(UndoLastCommitAction.ID, UndoLastCommitAction.LABEL, 'git-action undo-last-commit', gitService);
this.storageService = storageService;
}

public run():Promise {
Expand Down
4 changes: 4 additions & 0 deletions src/vs/workbench/parts/git/browser/gitServices.ts
Original file line number Diff line number Diff line change
Expand Up @@ -663,6 +663,10 @@ export class GitService extends ee.EventEmitter
return this.run(git.ServiceOperations.COMMIT, () => this.raw.commit(message, amend, stage));
}

public getCommitTemplate(): winjs.Promise {
return this.raw.getCommitTemplate();
}

public detectMimetypes(path: string, treeish: string = '~'): winjs.Promise {
return this.raw.detectMimetypes(path, treeish);
}
Expand Down
21 changes: 17 additions & 4 deletions src/vs/workbench/parts/git/browser/views/changes/changesView.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import {IEventService} from 'vs/platform/event/common/event';
import {CommonKeybindings} from 'vs/base/common/keyCodes';
import {IEditorGroupService} from 'vs/workbench/services/group/common/groupService';
import {IConfigurationService} from 'vs/platform/configuration/common/configuration';
import {IStorageService} from 'vs/platform/storage/common/storage';

import IGitService = git.IGitService;

Expand Down Expand Up @@ -89,7 +90,8 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV
@IGitService gitService: IGitService,
@IOutputService outputService: IOutputService,
@IEventService eventService: IEventService,
@IConfigurationService private configurationService: IConfigurationService
@IConfigurationService private configurationService: IConfigurationService,
@IStorageService private storageService: IStorageService
) {
super();

Expand Down Expand Up @@ -236,14 +238,24 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV

if (visible) {
this.tree.onVisible();
return this.onEditorsChanged(this.editorService.getActiveEditorInput());

return this.onCommitInputShown().then((_) =>
this.onEditorsChanged(this.editorService.getActiveEditorInput()));
} else {
this.tree.onHidden();
return WinJS.TPromise.as(null);
}
}

public onCommitInputShown(): WinJS.TPromise<void> {
if (!this.commitInputBox.value) {
return this.gitService.getCommitTemplate().then((template) => {
if (template) { this.commitInputBox.value = template; }
});
} else {
return WinJS.TPromise.as(null);
}
}

public getControl(): Tree.ITree {
return this.tree;
}
Expand Down Expand Up @@ -395,12 +407,13 @@ export class ChangesView extends EventEmitter.EventEmitter implements GitView.IV
}

private onGitOperationEnd(e: { operation: git.IGitOperation; error: any; }): void {
if (e.operation.id === git.ServiceOperations.COMMIT) {
if (e.operation.id === git.ServiceOperations.COMMIT || e.operation.id === git.ServiceOperations.RESET) {
if (this.commitInputBox) {
this.commitInputBox.enable();

if (!e.error) {
this.commitInputBox.value = '';
this.onCommitInputShown();
}
}
}
Expand Down
21 changes: 20 additions & 1 deletion src/vs/workbench/parts/git/common/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -222,7 +222,7 @@ export var ServiceOperations = {
BACKGROUND_FETCH: 'backgroundfetch',
PULL: 'pull',
PUSH: 'push',
SYNC: 'sync'
SYNC: 'sync',
};

// Service config
Expand Down Expand Up @@ -262,6 +262,23 @@ export interface IPushOptions {
setUpstream?: boolean;
}

/**
* These are `git log` options.
* The use case driving this is getting the previous commit message, message only.
* @example prevCount: 1, format: '%B' executes `git log -1 --format=%B`
* */
export interface ILogOptions {
/**
* @example `git log -1 --format=%B` to get the last commit log, message only
*/
prevCount?: number;

/**
* @example format: "%B" translates to `git log --format=%B` to get the message only
*/
format?: string;
}

export interface IRawGitService {
onOutput: Event<string>;
getVersion(): TPromise<string>;
Expand All @@ -284,6 +301,7 @@ export interface IRawGitService {
commit(message:string, amend?: boolean, stage?: boolean): TPromise<IRawStatus>;
detectMimetypes(path: string, treeish?: string): TPromise<string[]>;
show(path: string, treeish?: string): TPromise<string>;
getCommitTemplate(): TPromise<string>;
}

export var GIT_SERVICE_ID = 'gitService';
Expand Down Expand Up @@ -320,6 +338,7 @@ export interface IGitService extends IEventEmitter {
isIdle(): boolean;
getRunningOperations(): IGitOperation[];
getAutoFetcher(): IAutoFetcher;
getCommitTemplate(): TPromise<string>;
}

export interface IAskpassService {
Expand Down
6 changes: 6 additions & 0 deletions src/vs/workbench/parts/git/common/gitIpc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,7 @@ export interface IGitChannel extends IChannel {
call(command: 'detectMimetypes', args: [string, string]): TPromise<string[]>;
call(command: 'show', args: [string, string]): TPromise<string>;
call(command: 'onOutput'): TPromise<void>;
call(command: 'getCommitTemplate'): TPromise<string>;
call(command: string, args: any): TPromise<any>;
}

Expand Down Expand Up @@ -117,6 +118,7 @@ export class GitChannel implements IGitChannel {
case 'detectMimetypes': return this.service.then(s => s.detectMimetypes(args[0], args[1]));
case 'show': return this.service.then(s => s.show(args[0], args[1]));
case 'onOutput': return this.service.then(s => eventToCall(s.onOutput));
case 'getCommitTemplate': return this.service.then(s => s.getCommitTemplate());
}
}
}
Expand Down Expand Up @@ -217,6 +219,10 @@ export class GitChannelClient implements IRawGitService {
show(path: string, treeish?: string): TPromise<string> {
return this.channel.call('show', [path, treeish]);
}

getCommitTemplate(): TPromise<string> {
return this.channel.call('getCommitTemplate');
}
}

export interface IAskpassChannel extends IChannel {
Expand Down
8 changes: 8 additions & 0 deletions src/vs/workbench/parts/git/common/noopGitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -101,4 +101,12 @@ export class NoOpGitService implements IRawGitService {
show(path: string, treeish?: string): TPromise<string> {
return TPromise.as(null);
}

getLog(): TPromise<string> {
return TPromise.as(null);
}

getCommitTemplate(): TPromise<string> {
return TPromise.as(null);
}
}
14 changes: 13 additions & 1 deletion src/vs/workbench/parts/git/node/git.lib.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { assign } from 'vs/base/common/objects';
import { v4 as UUIDv4 } from 'vs/base/common/uuid';
import { localize } from 'vs/nls';
import { uniqueFilter } from 'vs/base/common/arrays';
import { IRawFileStatus, RefType, IRef, IBranch, IRemote, GitErrorCodes, IPushOptions } from 'vs/workbench/parts/git/common/git';
import { IRawFileStatus, RefType, IRef, IBranch, IRemote, GitErrorCodes, IPushOptions, ILogOptions } from 'vs/workbench/parts/git/common/git';
import { detectMimesFromStream } from 'vs/base/node/mime';
import { IFileOperationResult, FileOperationResult } from 'vs/platform/files/common/files';
import { spawn, ChildProcess } from 'child_process';
Expand Down Expand Up @@ -557,6 +557,18 @@ export class Repository {
return this.run(['rev-parse', '--show-toplevel'], { log: false }).then(result => result.stdout.trim());
}

/** Only implemented for use case `git log` and `git log -N`. */
getLog(options?: ILogOptions): TPromise<string> {
const args = ['log'];

if (options) {
if (options.prevCount) { args.push(`-${options.prevCount}`); }
if (options.format) { args.push(`--format=${options.format}`); }
}

return this.run(args, { log: false }).then(result => result.stdout.trim());
}

getStatus(): TPromise<IRawFileStatus[]> {
return this.run(['status', '-z', '-u'], { log: false }).then((executionResult) => {
const status = executionResult.stdout;
Expand Down
44 changes: 44 additions & 0 deletions src/vs/workbench/parts/git/node/rawGitService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
'use strict';

import * as fs from 'fs';
import { join } from 'path';
import { TPromise, Promise } from 'vs/base/common/winjs.base';
import { detectMimesFromFile, detectMimesFromStream } from 'vs/base/node/mime';
Expand Down Expand Up @@ -191,4 +192,47 @@ export class RawGitService implements IRawGitService {
return TPromise.wrapError<string>(e);
});
}

/**
* Reads the commit.template git config setting. If exists, then tries to load the contents of the file specified by that setting and returns these contents.
*/
getCommitTemplate(): TPromise<string> {
return this.repo.run(['config', '--get', 'commit.template']).then(execResult => execResult, err => '').then(execResult => {
return execResult ? this.readCommitTemplateFile(execResult.stdout.trim()) : '';
});
}

/**
* Reads the given file, if exists and is valid.
* @returns commit template file contents if exists and valid, else ""
*/
private readCommitTemplateFile(file: string): string {
try {
// // This is resolving to [repo]\.build\electron\~\.gitmessage
// let fullPath = resolve(file)
// console.log(`file: ${file}, fullPath: ${fullPath}`)
// return fs.existsSync(fullPath) ? fs.readFileSync(file, 'utf8') : '';
// Check the file itself
if (fs.existsSync(file)) {
return fs.readFileSync(file, 'utf8');
} else {
// File doesn't exist. Try converting ~/path to absolute path

// Try checking in local repo git folder (This is wrong interpretation oy)
let repo_file = file.replace('~', `${this.repo.path}\\.git`).replace('/', '\\');
if (fs.existsSync(repo_file)) {
return fs.readFileSync(repo_file, 'utf8');
} else {
// Check global (e.g. Windows user folder, Linux: home git config)
// not implemented

console.warn(`file doesnt exist in repo local git config. global git config template not implemented. (commit template file: ${file})`);
return '';
}
}
} catch (error) {
console.error(`Error reading file. file: ${file}, error: ${error.message})`);
return '';
}
}
}