From 6d8a37a10f4ab0fa50e0f9fbe371ae4cea032e51 Mon Sep 17 00:00:00 2001 From: Eric Amodio Date: Tue, 28 Mar 2017 00:24:55 -0400 Subject: [PATCH] Fixes #56 - Handle file names with spaces --- src/git/parsers/logParser.ts | 67 +++++++++++++++++------------------------ src/git/parsers/statusParser.ts | 19 +++++++++--- 2 files changed, 42 insertions(+), 44 deletions(-) diff --git a/src/git/parsers/logParser.ts b/src/git/parsers/logParser.ts index ff54227..5aa32c3 100644 --- a/src/git/parsers/logParser.ts +++ b/src/git/parsers/logParser.ts @@ -25,6 +25,8 @@ interface ILogEntry { summary?: string; } +const diffRegex = /diff --git a\/(.*) b\/(.*)/; + export class GitLogParser { private static _parseEntries(data: string, isRepoPath: boolean, maxCount: number | undefined, reverse: boolean): ILogEntry[] { @@ -103,7 +105,8 @@ export class GitLogParser { let diff = false; while (++position < lines.length) { - lineParts = lines[position].split(' '); + const line = lines[position]; + lineParts = line.split(' '); if (Git.shaRegex.test(lineParts[0])) { position--; @@ -114,8 +117,9 @@ export class GitLogParser { if (lineParts[0] === 'diff') { diff = true; - entry.fileName = lineParts[2].substring(2); - const originalFileName = lineParts[3].substring(2); + const matches = diffRegex.exec(line); + entry.fileName = matches[1]; + const originalFileName = matches[2]; if (entry.fileName !== originalFileName) { entry.originalFileName = originalFileName; } @@ -127,22 +131,11 @@ export class GitLogParser { } const status = { - status: lineParts[0][0] as GitStatusFileStatus, - fileName: lineParts[0].substring(1), + status: line[0] as GitStatusFileStatus, + fileName: line.substring(1), originalFileName: undefined as string }; - - const index = status.fileName.indexOf('\t') + 1; - if (index) { - const next = status.fileName.indexOf('\t', index) + 1; - if (next) { - status.originalFileName = status.fileName.substring(index, next - 1); - status.fileName = status.fileName.substring(next); - } - else { - status.fileName = status.fileName.substring(index); - } - } + this._parseFileName(status); entry.fileStatuses.push(status); } @@ -153,28 +146,10 @@ export class GitLogParser { } else { position += 2; - lineParts = lines[position].split(' '); - if (lineParts.length === 1) { - entry.status = lineParts[0][0] as GitStatusFileStatus; - entry.fileName = lineParts[0].substring(1); - } - else { - entry.status = lineParts[3][0] as GitStatusFileStatus; - entry.fileName = lineParts[0].substring(1); - position += 4; - } - - const index = entry.fileName.indexOf('\t') + 1; - if (index) { - const next = entry.fileName.indexOf('\t', index) + 1; - if (next) { - entry.originalFileName = entry.fileName.substring(index, next - 1); - entry.fileName = entry.fileName.substring(next); - } - else { - entry.fileName = entry.fileName.substring(index); - } - } + const line = lines[position]; + entry.status = line[0] as GitStatusFileStatus; + entry.fileName = line.substring(1); + this._parseFileName(entry); } entries.push(entry); @@ -284,4 +259,18 @@ export class GitLogParser { truncated: !!(maxCount && entries.length >= maxCount) } as IGitLog; } + + private static _parseFileName(entry: { fileName?: string, originalFileName?: string }) { + const index = entry.fileName.indexOf('\t') + 1; + if (index) { + const next = entry.fileName.indexOf('\t', index) + 1; + if (next) { + entry.originalFileName = entry.fileName.substring(index, next - 1); + entry.fileName = entry.fileName.substring(next); + } + else { + entry.fileName = entry.fileName.substring(index); + } + } + } } \ No newline at end of file diff --git a/src/git/parsers/statusParser.ts b/src/git/parsers/statusParser.ts index 18c05c4..7c60def 100644 --- a/src/git/parsers/statusParser.ts +++ b/src/git/parsers/statusParser.ts @@ -57,7 +57,16 @@ export class GitStatusParser { } } else { - const entry = this._parseFileEntry(line.substring(0, 2), line.substring(3)); + let entry: IFileStatusEntry; + const rawStatus = line.substring(0, 2); + let fileName = line.substring(3); + if (rawStatus[0] === 'R') { + const [file1, file2] = fileName.replace(/\"/g, '').split('->'); + entry = this._parseFileEntry(rawStatus, file2.trim(), file1.trim()); + } + else { + entry = this._parseFileEntry(rawStatus, fileName); + } status.files.push(new GitStatusFile(repoPath, entry.status, entry.staged, entry.fileName, entry.originalFileName)); } } @@ -91,17 +100,17 @@ export class GitStatusParser { let entry: IFileStatusEntry; switch (lineParts[0][0]) { case '1': // normal - entry = this._parseFileEntry(lineParts[1], lineParts[8]); + entry = this._parseFileEntry(lineParts[1], lineParts.slice(8).join(' ')); break; case '2': // rename - const file = lineParts[9].split('\t'); + const file = lineParts.slice(9).join(' ').split('\t'); entry = this._parseFileEntry(lineParts[1], file[0], file[1]); break; case 'u': // unmerged - entry = this._parseFileEntry(lineParts[1], lineParts[10]); + entry = this._parseFileEntry(lineParts[1], lineParts.slice(10).join(' ')); break; case '?': // untracked - entry = this._parseFileEntry(' ?', lineParts[1]); + entry = this._parseFileEntry(' ?', lineParts.slice(1).join(' ')); break; }