mirror of
https://github.com/ckaczor/vscode-gitlens.git
synced 2026-01-16 17:25:40 -05:00
Fixes issues with changes showing wrong diff
Refactors diff parsing
This commit is contained in:
@@ -6,35 +6,26 @@ export interface GitDiffLine {
|
||||
state: 'added' | 'removed' | 'unchanged';
|
||||
}
|
||||
|
||||
export interface GitDiffChunkLine extends GitDiffLine {
|
||||
previous?: (GitDiffLine | undefined)[];
|
||||
}
|
||||
|
||||
export class GitDiffChunk {
|
||||
|
||||
private _chunk: string | undefined;
|
||||
private _current: (GitDiffLine | undefined)[] | undefined;
|
||||
private _previous: (GitDiffLine | undefined)[] | undefined;
|
||||
private _lines: GitDiffChunkLine[] | undefined;
|
||||
|
||||
constructor(chunk: string, public currentPosition: { start: number, end: number }, public previousPosition: { start: number, end: number }) {
|
||||
this._chunk = chunk;
|
||||
}
|
||||
|
||||
get current(): (GitDiffLine | undefined)[] {
|
||||
if (this._chunk !== undefined) {
|
||||
this.parseChunk();
|
||||
get lines(): GitDiffChunkLine[] {
|
||||
if (this._lines === undefined) {
|
||||
this._lines = GitDiffParser.parseChunk(this._chunk!);
|
||||
this._chunk = undefined;
|
||||
}
|
||||
|
||||
return this._current!;
|
||||
}
|
||||
|
||||
get previous(): (GitDiffLine | undefined)[] {
|
||||
if (this._chunk !== undefined) {
|
||||
this.parseChunk();
|
||||
}
|
||||
|
||||
return this._previous!;
|
||||
}
|
||||
|
||||
private parseChunk() {
|
||||
[this._current, this._previous] = GitDiffParser.parseChunk(this._chunk!);
|
||||
this._chunk = undefined;
|
||||
return this._lines;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
'use strict';
|
||||
import { Iterables, Strings } from '../../system';
|
||||
import { GitDiff, GitDiffChunk, GitDiffLine } from './../git';
|
||||
import { GitDiff, GitDiffChunk, GitDiffChunkLine, GitDiffLine } from './../git';
|
||||
|
||||
const unifiedDiffRegex = /^@@ -([\d]+),([\d]+) [+]([\d]+),([\d]+) @@([\s\S]*?)(?=^@@)/gm;
|
||||
|
||||
@@ -39,36 +39,81 @@ export class GitDiffParser {
|
||||
return diff;
|
||||
}
|
||||
|
||||
static parseChunk(chunk: string): [(GitDiffLine | undefined)[], (GitDiffLine | undefined)[]] {
|
||||
static parseChunk(chunk: string): GitDiffChunkLine[] {
|
||||
const lines = Iterables.skip(Strings.lines(chunk), 1);
|
||||
|
||||
const current: (GitDiffLine | undefined)[] = [];
|
||||
const previous: (GitDiffLine | undefined)[] = [];
|
||||
const currentLines: (GitDiffLine | undefined)[] = [];
|
||||
const previousLines: (GitDiffLine | undefined)[] = [];
|
||||
|
||||
let removed = 0;
|
||||
for (const l of lines) {
|
||||
switch (l[0]) {
|
||||
case '+':
|
||||
current.push({
|
||||
currentLines.push({
|
||||
line: ` ${l.substring(1)}`,
|
||||
state: 'added'
|
||||
});
|
||||
previous.push(undefined);
|
||||
|
||||
if (removed > 0) {
|
||||
removed--;
|
||||
}
|
||||
else {
|
||||
previousLines.push(undefined);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case '-':
|
||||
current.push(undefined);
|
||||
previous.push({
|
||||
removed++;
|
||||
|
||||
previousLines.push({
|
||||
line: ` ${l.substring(1)}`,
|
||||
state: 'removed'
|
||||
});
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
current.push({ line: l, state: 'unchanged' });
|
||||
previous.push({ line: l, state: 'unchanged' });
|
||||
while (removed > 0) {
|
||||
removed--;
|
||||
currentLines.push(undefined);
|
||||
}
|
||||
|
||||
currentLines.push({ line: l, state: 'unchanged' });
|
||||
previousLines.push({ line: l, state: 'unchanged' });
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return [current, previous];
|
||||
const chunkLines: GitDiffChunkLine[] = [];
|
||||
|
||||
let chunkLine: GitDiffChunkLine | undefined = undefined;
|
||||
let current: GitDiffLine | undefined = undefined;
|
||||
|
||||
for (let i = 0; i < currentLines.length; i++) {
|
||||
current = currentLines[i];
|
||||
if (current === undefined) {
|
||||
// Don't think we need to worry about this case because the diff will always have "padding" (i.e. unchanged lines) around each chunk
|
||||
if (chunkLine === undefined) continue;
|
||||
|
||||
if (chunkLine.previous === undefined) {
|
||||
chunkLine.previous = [previousLines[i]];
|
||||
continue;
|
||||
}
|
||||
|
||||
chunkLine.previous.push(previousLines[i]);
|
||||
continue;
|
||||
}
|
||||
|
||||
chunkLine = {
|
||||
line: current.line,
|
||||
state: current.state,
|
||||
previous: [previousLines[i]]
|
||||
};
|
||||
chunkLines.push(chunkLine);
|
||||
}
|
||||
|
||||
return chunkLines;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user