Adds diff info to the active line hover for uncommitted changes

This commit is contained in:
Eric Amodio
2017-05-22 16:16:17 -04:00
parent ff1597d64f
commit 19e523d6e4
6 changed files with 208 additions and 13 deletions

View File

@@ -9,6 +9,7 @@ import * as tmp from 'tmp';
export { IGit };
export * from './models/models';
export * from './parsers/blameParser';
export * from './parsers/diffParser';
export * from './parsers/logParser';
export * from './parsers/stashParser';
export * from './parsers/statusParser';
@@ -160,6 +161,18 @@ export class Git {
}
}
static diff(repoPath: string, fileName: string, sha1?: string, sha2?: string) {
const params = [`diff`, `--diff-filter=M`, `-M`];
if (sha1) {
params.push(sha1);
}
if (sha2) {
params.push(sha2);
}
return gitCommand(repoPath, ...params, '--', fileName);
}
static diff_nameStatus(repoPath: string, sha1?: string, sha2?: string) {
const params = [`diff`, `--name-status`, `-M`];
if (sha1) {

18
src/git/models/diff.ts Normal file
View File

@@ -0,0 +1,18 @@
'use strict';
export interface IGitDiffChunk {
chunk?: string;
original: (string | undefined)[];
originalStart: number;
originalEnd: number;
changes: (string | undefined)[];
changesStart: number;
changesEnd: number;
}
export interface IGitDiff {
diff?: string;
chunks: IGitDiffChunk[];
}

View File

@@ -2,6 +2,7 @@
export * from './blame';
export * from './branch';
export * from './commit';
export * from './diff';
export * from './log';
export * from './logCommit';
export * from './remote';

View File

@@ -0,0 +1,45 @@
'use strict';
import { IGitDiff, IGitDiffChunk } from './../git';
const unifiedDiffRegex = /^@@ -([\d]+),([\d]+) [+]([\d]+),([\d]+) @@([\s\S]*?)(?=^@@)/gm;
export class GitDiffParser {
static parse(data: string, debug: boolean = false): IGitDiff | undefined {
if (!data) return undefined;
const chunks: IGitDiffChunk[] = [];
let match: RegExpExecArray | null = null;
do {
match = unifiedDiffRegex.exec(`${data}\n@@`);
if (match == null) break;
const originalStart = +match[1];
const changedStart = +match[3];
const chunk = match[5];
const lines = chunk.split('\n').slice(1);
const original = lines.filter(l => l[0] !== '+').map(l => (l[0] === '-') ? l.substring(1) : undefined);
const changed = lines.filter(l => l[0] !== '-').map(l => (l[0] === '+') ? l.substring(1) : undefined);
chunks.push({
chunk: debug ? chunk : undefined,
original: original,
originalStart: originalStart,
originalEnd: originalStart + +match[2],
changes: changed,
changesStart: changedStart,
changesEnd: changedStart + +match[4]
});
} while (match != null);
if (!chunks.length) return undefined;
const diff = {
diff: debug ? data : undefined,
chunks: chunks
} as IGitDiff;
return diff;
}
}