gitlify
Version:
A powerful CLI tool to analyze uncommitted git changes with detailed reports, function detection, and beautiful terminal output
132 lines (109 loc) • 3.46 kB
JavaScript
class DiffParser {
parseDiff(diffData) {
const files = [];
const combinedDiff = diffData.combined;
if (!combinedDiff.trim()) {
return files;
}
const diffBlocks = this.splitDiffIntoBlocks(combinedDiff);
for (const block of diffBlocks) {
const fileInfo = this.parseDiffBlock(block);
if (fileInfo) {
files.push(fileInfo);
}
}
return files;
}
splitDiffIntoBlocks(diff) {
const blocks = [];
const lines = diff.split('\n');
let currentBlock = [];
for (const line of lines) {
if (line.startsWith('diff --git')) {
if (currentBlock.length > 0) {
blocks.push(currentBlock.join('\n'));
}
currentBlock = [line];
} else {
currentBlock.push(line);
}
}
if (currentBlock.length > 0) {
blocks.push(currentBlock.join('\n'));
}
return blocks;
}
parseDiffBlock(block) {
const lines = block.split('\n');
if (lines.length === 0) return null;
// Extract file path from diff header
const diffHeader = lines[0];
const fileMatch = diffHeader.match(/diff --git a\/(.+) b\/(.+)/);
if (!fileMatch) return null;
const filePath = fileMatch[1];
// Parse hunks (chunks of changes)
const hunks = this.parseHunks(lines.slice(1));
// Calculate totals
let totalAdditions = 0;
let totalDeletions = 0;
const changedLines = [];
for (const hunk of hunks) {
totalAdditions += hunk.additions;
totalDeletions += hunk.deletions;
changedLines.push(...hunk.changedLines);
}
return {
filePath,
totalAdditions,
totalDeletions,
hunks,
changedLines: changedLines.sort((a, b) => a.lineNumber - b.lineNumber)
};
}
parseHunks(lines) {
const hunks = [];
let currentHunk = null;
for (const line of lines) {
// Hunk header: @@ -oldStart,oldCount +newStart,newCount @@
const hunkMatch = line.match(/^@@ -(\d+),?(\d*) \+(\d+),?(\d*) @@/);
if (hunkMatch) {
if (currentHunk) {
hunks.push(currentHunk);
}
const [, oldStart, oldCount, newStart, newCount] = hunkMatch;
currentHunk = {
oldStart: parseInt(oldStart),
oldCount: parseInt(oldCount) || 1,
newStart: parseInt(newStart),
newCount: parseInt(newCount) || 1,
additions: 0,
deletions: 0,
changedLines: []
};
continue;
}
if (!currentHunk) continue;
// Count additions and deletions
if (line.startsWith('+') && !line.startsWith('+++')) {
currentHunk.additions++;
currentHunk.changedLines.push({
type: 'addition',
lineNumber: currentHunk.newStart + currentHunk.additions - 1,
content: line.substring(1)
});
} else if (line.startsWith('-') && !line.startsWith('---')) {
currentHunk.deletions++;
currentHunk.changedLines.push({
type: 'deletion',
lineNumber: currentHunk.oldStart + currentHunk.deletions - 1,
content: line.substring(1)
});
}
}
if (currentHunk) {
hunks.push(currentHunk);
}
return hunks;
}
}
module.exports = DiffParser;