git: add optional 'signoff' to commits

This commit is contained in:
Fabian Lauer 2016-08-10 23:13:40 +02:00
parent dde41be023
commit 52b469e85b
7 changed files with 68 additions and 13 deletions

View file

@ -736,6 +736,24 @@ export class CommitAction extends BaseCommitAction {
}
export class CommitSignedOffAction extends BaseCommitAction {
static ID = 'workbench.action.git.commitSignedOff';
constructor(commitState: ICommitState, @IGitService gitService: IGitService) {
super(commitState, CommitAction.ID, nls.localize('commitStagedSignedOff', "Commit Staged (Signed Off)"), 'git-action commit-signed-off', gitService);
}
public run(context?: any):Promise {
if (!this.commitState.getCommitMessage()) {
this.commitState.onEmptyCommitMessage();
return TPromise.as(null);
}
return this.gitService.commit(this.commitState.getCommitMessage(), undefined, undefined, true);
}
}
export class InputCommitAction extends GitAction {
static ID = 'workbench.action.git.input-commit';
@ -809,6 +827,39 @@ export class StageAndCommitAction extends BaseCommitAction {
}
}
export class StageAndCommitSignedOffAction extends BaseCommitAction {
static ID = 'workbench.action.git.stageAndCommitSignedOff';
constructor(commitState: ICommitState, @IGitService gitService: IGitService) {
super(commitState, StageAndCommitAction.ID, nls.localize('commitAllSignedOff', "Commit All (Signed Off)"), 'git-action stage-and-commit-signed-off', gitService);
}
protected isEnabled():boolean {
if (!this.gitService) {
return false;
}
if (!this.gitService.isIdle()) {
return false;
}
var status = this.gitService.getModel().getStatus();
return status.getIndexStatus().all().length > 0
|| status.getWorkingTreeStatus().all().length > 0;
}
public run(context?: any):Promise {
if (!this.commitState.getCommitMessage()) {
this.commitState.onEmptyCommitMessage();
return TPromise.as(null);
}
return this.gitService.commit(this.commitState.getCommitMessage(), false, true, true);
}
}
export class SmartCommitAction extends BaseCommitAction {
static ID = 'workbench.action.git.commitAll';

View file

@ -687,8 +687,8 @@ export class GitService extends ee.EventEmitter
}
}
public commit(message:string, amend: boolean = false, stage: boolean = false): winjs.Promise {
return this.run(git.ServiceOperations.COMMIT, () => this.raw.commit(message, amend, stage));
public commit(message:string, amend: boolean = false, stage: boolean = false, signoff: boolean = false): winjs.Promise {
return this.run(git.ServiceOperations.COMMIT, () => this.raw.commit(message, amend, stage, signoff));
}
public getCommitTemplate(): winjs.Promise {

View file

@ -283,7 +283,7 @@ export interface IRawGitService {
pull(rebase?: boolean): TPromise<IRawStatus>;
push(remote?: string, name?: string, options?:IPushOptions): TPromise<IRawStatus>;
sync(): TPromise<IRawStatus>;
commit(message:string, amend?: boolean, stage?: boolean): TPromise<IRawStatus>;
commit(message:string, amend?: boolean, stage?: boolean, signoff?: boolean): TPromise<IRawStatus>;
detectMimetypes(path: string, treeish?: string): TPromise<string[]>;
show(path: string, treeish?: string): TPromise<string>;
getCommitTemplate(): TPromise<string>;
@ -311,7 +311,7 @@ export interface IGitService extends IEventEmitter {
pull(rebase?: boolean): TPromise<IModel>;
push(remote?: string, name?: string, options?:IPushOptions): TPromise<IModel>;
sync(): TPromise<IModel>;
commit(message:string, amend?: boolean, stage?: boolean): TPromise<IModel>;
commit(message:string, amend?: boolean, stage?: boolean, signoff?: boolean): TPromise<IModel>;
detectMimetypes(path: string, treeish?: string): TPromise<string[]>;
buffer(path: string, treeish?: string): TPromise<string>;

View file

@ -83,7 +83,7 @@ export interface IGitChannel extends IChannel {
call(command: 'pull', rebase?: boolean): TPromise<IPCRawStatus>;
call(command: 'push', args: [string, string, IPushOptions]): TPromise<IPCRawStatus>;
call(command: 'sync'): TPromise<IPCRawStatus>;
call(command: 'commit', args: [string, boolean, boolean]): TPromise<IPCRawStatus>;
call(command: 'commit', args: [string, boolean, boolean, boolean]): TPromise<IPCRawStatus>;
call(command: 'detectMimetypes', args: [string, string]): TPromise<string[]>;
call(command: 'show', args: [string, string]): TPromise<string>;
call(command: 'onOutput'): TPromise<void>;
@ -114,7 +114,7 @@ export class GitChannel implements IGitChannel {
case 'pull': return this.service.then(s => s.pull(args)).then(RawStatusSerializer.to);
case 'push': return this.service.then(s => s.push(args[0], args[1], args[2])).then(RawStatusSerializer.to);
case 'sync': return this.service.then(s => s.sync()).then(RawStatusSerializer.to);
case 'commit': return this.service.then(s => s.commit(args[0], args[1], args[2])).then(RawStatusSerializer.to);
case 'commit': return this.service.then(s => s.commit(args[0], args[1], args[2], args[3])).then(RawStatusSerializer.to);
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));
@ -208,8 +208,8 @@ export class GitChannelClient implements IRawGitService {
return this.channel.call('sync').then(RawStatusSerializer.from);
}
commit(message:string, amend?: boolean, stage?: boolean): TPromise<IRawStatus> {
return this.channel.call('commit', [message, amend, stage]).then(RawStatusSerializer.from);
commit(message:string, amend?: boolean, stage?: boolean, signoff?: boolean): TPromise<IRawStatus> {
return this.channel.call('commit', [message, amend, stage, signoff]).then(RawStatusSerializer.from);
}
detectMimetypes(path: string, treeish?: string): TPromise<string[]> {

View file

@ -90,7 +90,7 @@ export class NoOpGitService implements IRawGitService {
return TPromise.as(NoOpGitService.STATUS);
}
commit(message: string, amend?: boolean, stage?: boolean): TPromise<IRawStatus> {
commit(message: string, amend?: boolean, stage?: boolean, signoff?: boolean): TPromise<IRawStatus> {
return TPromise.as(NoOpGitService.STATUS);
}

View file

@ -411,7 +411,7 @@ export class Repository {
});
}
commit(message: string, all: boolean, amend: boolean): Promise {
commit(message: string, all: boolean, amend: boolean, signoff: boolean): Promise {
const args = ['commit', '--quiet', '--allow-empty-message', '--file', '-'];
if (all) {
@ -422,6 +422,10 @@ export class Repository {
args.push('--amend');
}
if (signoff) {
args.push('--signoff');
}
return this.run(args, { input: message || '' }).then(null, (commitErr: GitError) => {
if (/not possible because you have unmerged files/.test(commitErr.stderr)) {
commitErr.gitErrorCode = GitErrorCodes.UnmergedChanges;

View file

@ -150,7 +150,7 @@ export class RawGitService implements IRawGitService {
return this.repo.sync().then(() => this.status());
}
commit(message:string, amend?: boolean, stage?: boolean): TPromise<IRawStatus> {
commit(message:string, amend?: boolean, stage?: boolean, signoff?: boolean): TPromise<IRawStatus> {
let promise: Promise = TPromise.as(null);
if (stage) {
@ -158,7 +158,7 @@ export class RawGitService implements IRawGitService {
}
return promise
.then(() => this.repo.commit(message, stage, amend))
.then(() => this.repo.commit(message, stage, amend, signoff))
.then(() => this.status());
}
@ -221,7 +221,7 @@ export class DelayedRawGitService implements IRawGitService {
pull(rebase?: boolean): TPromise<IRawStatus> { return this.raw.then(r => r.pull(rebase)); }
push(remote?: string, name?: string, options?:IPushOptions): TPromise<IRawStatus> { return this.raw.then(r => r.push(remote, name, options)); }
sync(): TPromise<IRawStatus> { return this.raw.then(r => r.sync()); }
commit(message:string, amend?: boolean, stage?: boolean): TPromise<IRawStatus> { return this.raw.then(r => r.commit(message, amend, stage)); }
commit(message:string, amend?: boolean, stage?: boolean, signoff?: boolean): TPromise<IRawStatus> { return this.raw.then(r => r.commit(message, amend, stage, signoff)); }
detectMimetypes(path: string, treeish?: string): TPromise<string[]> { return this.raw.then(r => r.detectMimetypes(path, treeish)); }
show(path: string, treeish?: string): TPromise<string> { return this.raw.then(r => r.show(path, treeish)); }
getCommitTemplate(): TPromise<string> { return this.raw.then(r => r.getCommitTemplate()); }