From 01292b41740349747ed2748cb7aefa7123f6e386 Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Tue, 11 Dec 2018 10:38:36 -0800 Subject: [PATCH 1/2] Add Git log, globalConfig, and tree diff API --- extensions/git/src/api/api1.ts | 40 +++++-- extensions/git/src/api/git.d.ts | 13 +++ extensions/git/src/git.ts | 161 +++++++++++++++++++++++++--- extensions/git/src/repository.ts | 33 ++++-- extensions/git/src/test/git.test.ts | 12 ++- 5 files changed, 226 insertions(+), 33 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 9469580d97b..9d8a5901786 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -5,7 +5,7 @@ import { Model } from '../model'; import { Repository as BaseRepository, Resource } from '../repository'; -import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status } from './git'; +import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, GitLogOptions } from './git'; import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode'; import { mapEvent } from '../util'; @@ -76,6 +76,10 @@ export class ApiRepository implements Repository { return this._repository.setConfig(key, value); } + getGlobalConfig(key: string): Promise { + return this._repository.getGlobalConfig(key); + } + getObjectDetails(treeish: string, path: string): Promise<{ mode: string; object: string; size: number; }> { return this._repository.getObjectDetails(treeish, path); } @@ -104,28 +108,38 @@ export class ApiRepository implements Repository { return this._repository.diff(cached); } - diffWithHEAD(path: string): Promise { - return this._repository.diffWithHEAD(path); + diffWithHEAD(): Promise; + diffWithHEAD(path: string): Promise; + diffWithHEAD(path?: string): Promise { + return path ? this._repository.diffWithHEAD(path) : this._repository.diffWithHEAD(); } - diffWith(ref: string, path: string): Promise { - return this._repository.diffWith(ref, path); + diffWith(ref: string): Promise; + diffWith(ref: string, path: string): Promise; + diffWith(ref: string, path?: string): Promise { + return path ? this._repository.diffWith(ref, path) : this._repository.diffWith(ref); } - diffIndexWithHEAD(path: string): Promise { - return this._repository.diffIndexWithHEAD(path); + diffIndexWithHEAD(): Promise; + diffIndexWithHEAD(path: string): Promise; + diffIndexWithHEAD(path?: string): Promise { + return path ? this._repository.diffIndexWithHEAD(path) : this._repository.diffIndexWithHEAD(); } - diffIndexWith(ref: string, path: string): Promise { - return this._repository.diffIndexWith(ref, path); + diffIndexWith(ref: string): Promise; + diffIndexWith(ref: string, path: string): Promise; + diffIndexWith(ref: string, path?: string): Promise { + return path ? this._repository.diffIndexWith(ref, path) : this._repository.diffIndexWith(ref); } diffBlobs(object1: string, object2: string): Promise { return this._repository.diffBlobs(object1, object2); } - diffBetween(ref1: string, ref2: string, path: string): Promise { - return this._repository.diffBetween(ref1, ref2, path); + diffBetween(ref1: string, ref2: string): Promise; + diffBetween(ref1: string, ref2: string, path: string): Promise; + diffBetween(ref1: string, ref2: string, path?: string): Promise { + return path ? this._repository.diffBetween(ref1, ref2, path) : this._repository.diffBetween(ref1, ref2); } hashObject(data: string): Promise { @@ -179,6 +193,10 @@ export class ApiRepository implements Repository { push(remoteName?: string, branchName?: string, setUpstream: boolean = false): Promise { return this._repository.pushTo(remoteName, branchName, setUpstream); } + + getLog(options?: GitLogOptions): Promise { + return this._repository.getLog(options); + } } export class ApiGit implements Git { diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index 1b3ed4d2dec..ff6ce04ab99 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -41,6 +41,7 @@ export interface Commit { readonly hash: string; readonly message: string; readonly parents: string[]; + readonly authorEmail?: string | undefined; } export interface Submodule { @@ -109,6 +110,10 @@ export interface RepositoryUIState { readonly onDidChange: Event; } +export interface GitLogOptions { + readonly maxEntries?: number; +} + export interface Repository { readonly rootUri: Uri; @@ -119,6 +124,7 @@ export interface Repository { getConfigs(): Promise<{ key: string; value: string; }[]>; getConfig(key: string): Promise; setConfig(key: string, value: string): Promise; + getGlobalConfig(key: string): Promise; getObjectDetails(treeish: string, path: string): Promise<{ mode: string, object: string, size: number }>; detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }>; @@ -130,11 +136,16 @@ export interface Repository { apply(patch: string, reverse?: boolean): Promise; diff(cached?: boolean): Promise; + diffWithHEAD(): Promise; diffWithHEAD(path: string): Promise; + diffWith(ref: string): Promise; diffWith(ref: string, path: string): Promise; + diffIndexWithHEAD(): Promise; diffIndexWithHEAD(path: string): Promise; + diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffBlobs(object1: string, object2: string): Promise; + diffBetween(ref1: string, ref2: string): Promise; diffBetween(ref1: string, ref2: string, path: string): Promise; hashObject(data: string): Promise; @@ -155,6 +166,8 @@ export interface Repository { fetch(remote?: string, ref?: string): Promise; pull(): Promise; push(remoteName?: string, branchName?: string, setUpstream?: boolean): Promise; + + getLog(options?: GitLogOptions): Promise; } export interface API { diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index 380ee42f411..d104d3cbdf4 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -12,9 +12,9 @@ import { EventEmitter } from 'events'; import iconv = require('iconv-lite'); import * as filetype from 'file-type'; import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; -import { CancellationToken } from 'vscode'; +import { CancellationToken, Uri } from 'vscode'; import { detectEncoding } from './encoding'; -import { Ref, RefType, Branch, Remote, GitErrorCodes } from './api/git'; +import { Ref, RefType, Branch, Remote, GitErrorCodes, GitLogOptions, Change, Status } from './api/git'; const readfile = denodeify(fs.readFile); @@ -311,6 +311,8 @@ function getGitErrorCode(stderr: string): string | undefined { return void 0; } +const COMMIT_FORMAT = '%H\n%ae\n%P\n%B'; + export class Git { readonly path: string; @@ -450,6 +452,7 @@ export interface Commit { hash: string; message: string; parents: string[]; + authorEmail?: string | undefined; } export class GitStatusParser { @@ -581,13 +584,13 @@ export function parseGitmodules(raw: string): Submodule[] { } export function parseGitCommit(raw: string): Commit | null { - const match = /^([0-9a-f]{40})\n(.*)\n([^]*)$/m.exec(raw.trim()); + const match = /^([0-9a-f]{40})\n(.*)\n(.*)\n([^]*)$/m.exec(raw.trim()); if (!match) { return null; } - const parents = match[2] ? match[2].split(' ') : []; - return { hash: match[1], message: match[3], parents }; + const parents = match[3] ? match[3].split(' ') : []; + return { hash: match[1], message: match[4], parents, authorEmail: match[2] }; } interface LsTreeElement { @@ -697,6 +700,38 @@ export class Repository { }); } + async getLog(options?: GitLogOptions): Promise { + const args = ['log']; + if (options) { + if (typeof options.maxEntries === 'number' && options.maxEntries > 0) { + args.push('-' + options.maxEntries); + } + } + + args.push(`--pretty=format:${COMMIT_FORMAT}%x00%x00`); + const gitResult = await this.run(args); + if (gitResult.exitCode) { + // An empty repo. + return []; + } + + const entries = gitResult.stdout.split('\x00\x00'); + const result: Commit[] = []; + for (let entry of entries) { + if (entry.startsWith('\n')) { + entry = entry.substring(1); + } + const commit = parseGitCommit(entry); + if (!commit) { + break; + } + + result.push(commit); + } + + return result; + } + async bufferString(object: string, encoding: string = 'utf8', autoGuessEncoding = false): Promise { const stdout = await this.buffer(object); @@ -851,25 +886,41 @@ export class Repository { return result.stdout; } - async diffWithHEAD(path: string): Promise { + async diffWithHEAD(path?: string): Promise { + if (!path) { + return await this.diffFiles(false); + } + const args = ['diff', '--', path]; const result = await this.run(args); return result.stdout; } - async diffWith(ref: string, path: string): Promise { + async diffWith(ref: string, path?: string): Promise { + if (!path) { + return await this.diffFiles(false, ref); + } + const args = ['diff', ref, '--', path]; const result = await this.run(args); return result.stdout; } - async diffIndexWithHEAD(path: string): Promise { + async diffIndexWithHEAD(path?: string): Promise { + if (!path) { + return await this.diffFiles(true); + } + const args = ['diff', '--cached', '--', path]; const result = await this.run(args); return result.stdout; } - async diffIndexWith(ref: string, path: string): Promise { + async diffIndexWith(ref: string, path?: string): Promise { + if (!path) { + return await this.diffFiles(true, ref); + } + const args = ['diff', '--cached', ref, '--', path]; const result = await this.run(args); return result.stdout; @@ -881,13 +932,99 @@ export class Repository { return result.stdout; } - async diffBetween(ref1: string, ref2: string, path: string): Promise { - const args = ['diff', `${ref1}...${ref2}`, '--', path]; + async diffBetween(ref1: string, ref2: string, path?: string): Promise { + const range = `${ref1}...${ref2}`; + if (!path) { + return await this.diffFiles(false, range); + } + + const args = ['diff', range, '--', path]; const result = await this.run(args); return result.stdout.trim(); } + private async diffFiles(cached: boolean, ref?: string): Promise { + const args = ['diff', '--name-status', '-z', '--diff-filter=ADMR']; + if (cached) { + args.push('--cached'); + } + + if (ref) { + args.push(ref); + } + + const gitResult = await this.run(args); + if (gitResult.exitCode) { + return []; + } + + const entries = gitResult.stdout.split('\x00'); + let index = 0; + const result: Change[] = []; + + entriesLoop: + while (index < entries.length - 1) { + const change = entries[index++]; + const resourcePath = entries[index++]; + if (!change || !resourcePath) { + break; + } + + const originalUri = Uri.file(path.isAbsolute(resourcePath) ? resourcePath : path.join(this.repositoryRoot, resourcePath)); + let status: Status = Status.UNTRACKED; + + // Copy or Rename status comes with a number, e.g. 'R100'. We don't need the number, so we use only first character of the status. + switch (change[0]) { + case 'M': + status = Status.MODIFIED; + break; + + case 'A': + status = Status.INDEX_ADDED; + break; + + case 'D': + status = Status.DELETED; + break; + + // Rename contains two paths, the second one is what the file is renamed/copied to. + case 'R': + if (index >= entries.length) { + break; + } + + const newPath = entries[index++]; + if (!newPath) { + break; + } + + const uri = Uri.file(path.isAbsolute(newPath) ? newPath : path.join(this.repositoryRoot, newPath)); + result.push({ + uri, + renameUri: uri, + originalUri, + status: Status.INDEX_RENAMED + }); + + continue; + + default: + // Unknown status + break entriesLoop; + } + + result.push({ + status, + originalUri, + uri: originalUri, + renameUri: originalUri, + }); + } + + return result; + } + async getMergeBase(ref1: string, ref2: string): Promise { const args = ['merge-base', ref1, ref2]; const result = await this.run(args); @@ -1529,7 +1666,7 @@ export class Repository { } async getCommit(ref: string): Promise { - const result = await this.run(['show', '-s', '--format=%H\n%P\n%B', ref]); + const result = await this.run(['show', '-s', `--format=${COMMIT_FORMAT}`, ref]); return parseGitCommit(result.stdout) || Promise.reject('bad commit format'); } diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index d188eea026e..e9650b905a7 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -13,7 +13,7 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; import * as fs from 'fs'; import { StatusBarCommands } from './statusbar'; -import { Branch, Ref, Remote, RefType, GitErrorCodes, Status } from './api/git'; +import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, GitLogOptions, Change } from './api/git'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); @@ -295,7 +295,8 @@ export const enum Operation { GetObjectDetails = 'GetObjectDetails', SubmoduleUpdate = 'SubmoduleUpdate', RebaseContinue = 'RebaseContinue', - Apply = 'Apply' + Apply = 'Apply', + Log = 'Log', } function isReadOnly(operation: Operation): boolean { @@ -697,10 +698,18 @@ export class Repository implements Disposable { return this.run(Operation.Config, () => this.repository.config('local', key)); } + getGlobalConfig(key: string): Promise { + return this.run(Operation.Config, () => this.repository.config('global', key)); + } + setConfig(key: string, value: string): Promise { return this.run(Operation.Config, () => this.repository.config('local', key, value)); } + getLog(options?: GitLogOptions): Promise { + return this.run(Operation.Log, () => this.repository.getLog(options)); + } + @throttle async status(): Promise { await this.run(Operation.Status); @@ -710,19 +719,27 @@ export class Repository implements Disposable { return this.run(Operation.Diff, () => this.repository.diff(cached)); } - diffWithHEAD(path: string): Promise { + diffWithHEAD(): Promise; + diffWithHEAD(path: string): Promise; + diffWithHEAD(path?: string | undefined): Promise { return this.run(Operation.Diff, () => this.repository.diffWithHEAD(path)); } - diffWith(ref: string, path: string): Promise { + diffWith(ref: string): Promise; + diffWith(ref: string, path: string): Promise; + diffWith(ref: string, path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffWith(ref, path)); } - diffIndexWithHEAD(path: string): Promise { + diffIndexWithHEAD(): Promise; + diffIndexWithHEAD(path: string): Promise; + diffIndexWithHEAD(path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffIndexWithHEAD(path)); } - diffIndexWith(ref: string, path: string): Promise { + diffIndexWith(ref: string): Promise; + diffIndexWith(ref: string, path: string): Promise; + diffIndexWith(ref: string, path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffIndexWith(ref, path)); } @@ -730,7 +747,9 @@ export class Repository implements Disposable { return this.run(Operation.Diff, () => this.repository.diffBlobs(object1, object2)); } - diffBetween(ref1: string, ref2: string, path: string): Promise { + diffBetween(ref1: string, ref2: string): Promise; + diffBetween(ref1: string, ref2: string, path: string): Promise; + diffBetween(ref1: string, ref2: string, path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffBetween(ref1, ref2, path)); } diff --git a/extensions/git/src/test/git.test.ts b/extensions/git/src/test/git.test.ts index 6b7af8c8684..e28cf10d192 100644 --- a/extensions/git/src/test/git.test.ts +++ b/extensions/git/src/test/git.test.ts @@ -177,37 +177,43 @@ suite('git', () => { suite('parseGitCommit', () => { test('single parent commit', function () { const GIT_OUTPUT_SINGLE_PARENT = `52c293a05038d865604c2284aa8698bd087915a1 +john.doe@mail.com 8e5a374372b8393906c7e380dbb09349c5385554 This is a commit message.`; assert.deepEqual(parseGitCommit(GIT_OUTPUT_SINGLE_PARENT), { hash: '52c293a05038d865604c2284aa8698bd087915a1', message: 'This is a commit message.', - parents: ['8e5a374372b8393906c7e380dbb09349c5385554'] + parents: ['8e5a374372b8393906c7e380dbb09349c5385554'], + authorEmail: 'john.doe@mail.com', }); }); test('multiple parent commits', function () { const GIT_OUTPUT_MULTIPLE_PARENTS = `52c293a05038d865604c2284aa8698bd087915a1 +john.doe@mail.com 8e5a374372b8393906c7e380dbb09349c5385554 df27d8c75b129ab9b178b386077da2822101b217 This is a commit message.`; assert.deepEqual(parseGitCommit(GIT_OUTPUT_MULTIPLE_PARENTS), { hash: '52c293a05038d865604c2284aa8698bd087915a1', message: 'This is a commit message.', - parents: ['8e5a374372b8393906c7e380dbb09349c5385554', 'df27d8c75b129ab9b178b386077da2822101b217'] + parents: ['8e5a374372b8393906c7e380dbb09349c5385554', 'df27d8c75b129ab9b178b386077da2822101b217'], + authorEmail: 'john.doe@mail.com', }); }); test('no parent commits', function () { const GIT_OUTPUT_NO_PARENTS = `52c293a05038d865604c2284aa8698bd087915a1 +john.doe@mail.com This is a commit message.`; assert.deepEqual(parseGitCommit(GIT_OUTPUT_NO_PARENTS), { hash: '52c293a05038d865604c2284aa8698bd087915a1', message: 'This is a commit message.', - parents: [] + parents: [], + authorEmail: 'john.doe@mail.com', }); }); }); From 04c3dde6e49613d716dd16ef253c6351d8b5077d Mon Sep 17 00:00:00 2001 From: Ilya Biryukov Date: Mon, 7 Jan 2019 11:31:28 -0800 Subject: [PATCH 2/2] Address PR feedback on Git provide APIs --- extensions/git/src/api/api1.ts | 16 ++++++------ extensions/git/src/api/git.d.ts | 8 ++++-- extensions/git/src/git.ts | 44 ++++++++++++++++++++++---------- extensions/git/src/repository.ts | 11 +++++--- 4 files changed, 53 insertions(+), 26 deletions(-) diff --git a/extensions/git/src/api/api1.ts b/extensions/git/src/api/api1.ts index 9d8a5901786..769a646baeb 100644 --- a/extensions/git/src/api/api1.ts +++ b/extensions/git/src/api/api1.ts @@ -5,7 +5,7 @@ import { Model } from '../model'; import { Repository as BaseRepository, Resource } from '../repository'; -import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, GitLogOptions } from './git'; +import { InputBox, Git, API, Repository, Remote, RepositoryState, Branch, Ref, Submodule, Commit, Change, RepositoryUIState, Status, LogOptions } from './git'; import { Event, SourceControlInputBox, Uri, SourceControl } from 'vscode'; import { mapEvent } from '../util'; @@ -111,25 +111,25 @@ export class ApiRepository implements Repository { diffWithHEAD(): Promise; diffWithHEAD(path: string): Promise; diffWithHEAD(path?: string): Promise { - return path ? this._repository.diffWithHEAD(path) : this._repository.diffWithHEAD(); + return this._repository.diffWithHEAD(path); } diffWith(ref: string): Promise; diffWith(ref: string, path: string): Promise; diffWith(ref: string, path?: string): Promise { - return path ? this._repository.diffWith(ref, path) : this._repository.diffWith(ref); + return this._repository.diffWith(ref, path); } diffIndexWithHEAD(): Promise; diffIndexWithHEAD(path: string): Promise; diffIndexWithHEAD(path?: string): Promise { - return path ? this._repository.diffIndexWithHEAD(path) : this._repository.diffIndexWithHEAD(); + return this._repository.diffIndexWithHEAD(path); } diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; diffIndexWith(ref: string, path?: string): Promise { - return path ? this._repository.diffIndexWith(ref, path) : this._repository.diffIndexWith(ref); + return this._repository.diffIndexWith(ref, path); } diffBlobs(object1: string, object2: string): Promise { @@ -139,7 +139,7 @@ export class ApiRepository implements Repository { diffBetween(ref1: string, ref2: string): Promise; diffBetween(ref1: string, ref2: string, path: string): Promise; diffBetween(ref1: string, ref2: string, path?: string): Promise { - return path ? this._repository.diffBetween(ref1, ref2, path) : this._repository.diffBetween(ref1, ref2); + return this._repository.diffBetween(ref1, ref2, path); } hashObject(data: string): Promise { @@ -194,8 +194,8 @@ export class ApiRepository implements Repository { return this._repository.pushTo(remoteName, branchName, setUpstream); } - getLog(options?: GitLogOptions): Promise { - return this._repository.getLog(options); + log(options?: LogOptions): Promise { + return this._repository.log(options); } } diff --git a/extensions/git/src/api/git.d.ts b/extensions/git/src/api/git.d.ts index ff6ce04ab99..c5e2b3bc9d2 100644 --- a/extensions/git/src/api/git.d.ts +++ b/extensions/git/src/api/git.d.ts @@ -110,7 +110,11 @@ export interface RepositoryUIState { readonly onDidChange: Event; } -export interface GitLogOptions { +/** + * Log options. + */ +export interface LogOptions { + /** Max number of log entries to retrieve. If not specified, the default is 32. */ readonly maxEntries?: number; } @@ -167,7 +171,7 @@ export interface Repository { pull(): Promise; push(remoteName?: string, branchName?: string, setUpstream?: boolean): Promise; - getLog(options?: GitLogOptions): Promise; + log(options?: LogOptions): Promise; } export interface API { diff --git a/extensions/git/src/git.ts b/extensions/git/src/git.ts index d104d3cbdf4..a06598f5974 100644 --- a/extensions/git/src/git.ts +++ b/extensions/git/src/git.ts @@ -14,7 +14,7 @@ import * as filetype from 'file-type'; import { assign, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util'; import { CancellationToken, Uri } from 'vscode'; import { detectEncoding } from './encoding'; -import { Ref, RefType, Branch, Remote, GitErrorCodes, GitLogOptions, Change, Status } from './api/git'; +import { Ref, RefType, Branch, Remote, GitErrorCodes, LogOptions, Change, Status } from './api/git'; const readfile = denodeify(fs.readFile); @@ -700,33 +700,36 @@ export class Repository { }); } - async getLog(options?: GitLogOptions): Promise { - const args = ['log']; - if (options) { - if (typeof options.maxEntries === 'number' && options.maxEntries > 0) { - args.push('-' + options.maxEntries); - } - } - - args.push(`--pretty=format:${COMMIT_FORMAT}%x00%x00`); + async log(options?: LogOptions): Promise { + const maxEntries = options && typeof options.maxEntries === 'number' && options.maxEntries > 0 ? options.maxEntries : 32; + const args = ['log', '-' + maxEntries, `--pretty=format:${COMMIT_FORMAT}%x00%x00`]; const gitResult = await this.run(args); if (gitResult.exitCode) { // An empty repo. return []; } - const entries = gitResult.stdout.split('\x00\x00'); + const s = gitResult.stdout; const result: Commit[] = []; - for (let entry of entries) { + let index = 0; + while (index < s.length) { + let nextIndex = s.indexOf('\x00\x00', index); + if (nextIndex === -1) { + nextIndex = s.length; + } + + let entry = s.substr(index, nextIndex - index); if (entry.startsWith('\n')) { entry = entry.substring(1); } + const commit = parseGitCommit(entry); if (!commit) { break; } result.push(commit); + index = nextIndex + 2; } return result; @@ -886,7 +889,10 @@ export class Repository { return result.stdout; } - async diffWithHEAD(path?: string): Promise { + diffWithHEAD(): Promise; + diffWithHEAD(path: string): Promise; + diffWithHEAD(path?: string | undefined): Promise; + async diffWithHEAD(path?: string | undefined): Promise { if (!path) { return await this.diffFiles(false); } @@ -896,6 +902,9 @@ export class Repository { return result.stdout; } + diffWith(ref: string): Promise; + diffWith(ref: string, path: string): Promise; + diffWith(ref: string, path?: string | undefined): Promise; async diffWith(ref: string, path?: string): Promise { if (!path) { return await this.diffFiles(false, ref); @@ -906,6 +915,9 @@ export class Repository { return result.stdout; } + diffIndexWithHEAD(): Promise; + diffIndexWithHEAD(path: string): Promise; + diffIndexWithHEAD(path?: string | undefined): Promise; async diffIndexWithHEAD(path?: string): Promise { if (!path) { return await this.diffFiles(true); @@ -916,6 +928,9 @@ export class Repository { return result.stdout; } + diffIndexWith(ref: string): Promise; + diffIndexWith(ref: string, path: string): Promise; + diffIndexWith(ref: string, path?: string | undefined): Promise; async diffIndexWith(ref: string, path?: string): Promise { if (!path) { return await this.diffFiles(true, ref); @@ -932,6 +947,9 @@ export class Repository { return result.stdout; } + diffBetween(ref1: string, ref2: string): Promise; + diffBetween(ref1: string, ref2: string, path: string): Promise; + diffBetween(ref1: string, ref2: string, path?: string | undefined): Promise; async diffBetween(ref1: string, ref2: string, path?: string): Promise { const range = `${ref1}...${ref2}`; if (!path) { diff --git a/extensions/git/src/repository.ts b/extensions/git/src/repository.ts index e9650b905a7..dc3399e3ec9 100644 --- a/extensions/git/src/repository.ts +++ b/extensions/git/src/repository.ts @@ -13,7 +13,7 @@ import * as path from 'path'; import * as nls from 'vscode-nls'; import * as fs from 'fs'; import { StatusBarCommands } from './statusbar'; -import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, GitLogOptions, Change } from './api/git'; +import { Branch, Ref, Remote, RefType, GitErrorCodes, Status, LogOptions, Change } from './api/git'; const timeout = (millis: number) => new Promise(c => setTimeout(c, millis)); @@ -706,8 +706,8 @@ export class Repository implements Disposable { return this.run(Operation.Config, () => this.repository.config('local', key, value)); } - getLog(options?: GitLogOptions): Promise { - return this.run(Operation.Log, () => this.repository.getLog(options)); + log(options?: LogOptions): Promise { + return this.run(Operation.Log, () => this.repository.log(options)); } @throttle @@ -721,24 +721,28 @@ export class Repository implements Disposable { diffWithHEAD(): Promise; diffWithHEAD(path: string): Promise; + diffWithHEAD(path?: string | undefined): Promise; diffWithHEAD(path?: string | undefined): Promise { return this.run(Operation.Diff, () => this.repository.diffWithHEAD(path)); } diffWith(ref: string): Promise; diffWith(ref: string, path: string): Promise; + diffWith(ref: string, path?: string | undefined): Promise; diffWith(ref: string, path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffWith(ref, path)); } diffIndexWithHEAD(): Promise; diffIndexWithHEAD(path: string): Promise; + diffIndexWithHEAD(path?: string | undefined): Promise; diffIndexWithHEAD(path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffIndexWithHEAD(path)); } diffIndexWith(ref: string): Promise; diffIndexWith(ref: string, path: string): Promise; + diffIndexWith(ref: string, path?: string | undefined): Promise; diffIndexWith(ref: string, path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffIndexWith(ref, path)); } @@ -749,6 +753,7 @@ export class Repository implements Disposable { diffBetween(ref1: string, ref2: string): Promise; diffBetween(ref1: string, ref2: string, path: string): Promise; + diffBetween(ref1: string, ref2: string, path?: string | undefined): Promise; diffBetween(ref1: string, ref2: string, path?: string): Promise { return this.run(Operation.Diff, () => this.repository.diffBetween(ref1, ref2, path)); }