RSS Git Download  Clone
Raw View History
Blames found: 1 Mode: php Binary: false


Hang on, we reloading big blames...
<?php declare(strict_types=1); namespace GitList\SCM\Diff; class Parse { private const TOKENS = [ '/^diff --c\s/' => 'start', '/^diff --cc\s/' => 'start', '/^diff --git\s/' => 'start', '/^diff -r\s/' => 'start', '/^new file mode \d+$/' => 'newFile', '/^deleted file mode \d+$/' => 'deletedFile', '/^index\s[\da-zA-Z]+\.\.[\da-zA-Z]+(\s(\d+))?$/' => 'index', '/^index\s([\da-zA-Z]+,)([\da-zA-Z]+\.\.[\da-zA-Z]+)(\s(\d+))?$/' => 'mergeIndex', '/^---\s/' => 'fromFile', '/^\+\+\+\s/' => 'toFile', '/^@@\s+(\-(\d+),?(\d+)?\s+)+(\+(\d+),?(\d+)?\s)+@@/' => 'hunk', '/^@@@\s+(\-(\d+),?(\d+)?\s+)+(\+(\d+),?(\d+)?\s)+@@@/' => 'hunk', '/^-/' => 'deletedLine', '/^\+/' => 'addedLine', ]; protected array $files = []; protected ?File $currentFile = null; protected ?Hunk $currentHunk = null; protected int $oldCounter = 0; protected int $newCounter = 0; protected int $deletedLines = 0; protected int $addedLines = 0; public function fromRawBlock(string $rawBlock) { $rawLines = explode(PHP_EOL, $rawBlock); $this->files = []; foreach ($rawLines as $rawLine) { $matched = false; foreach (self::TOKENS as $pattern => $action) { $matches = []; if (preg_match($pattern, $rawLine, $matches)) { $this->$action($rawLine, $matches); $matched = true; break; } } if (!$matched) { $this->line($rawLine); } } $this->clearAccumulator(); return $this->files; } protected function start(string $line, array $context): void { $this->clearAccumulator(); $line = str_replace($context[0], '', $line); $files = explode(' ', $line); $filename = str_replace('a/', '', $files[0]); $this->currentFile = new File($filename); } protected function newFile(string $line, array $context): void { $this->currentFile->setType(File::TYPE_NEW); } protected function deletedFile(string $line, array $context): void { $this->currentFile->setType(File::TYPE_DELETED); } protected function index(string $line, array $context): void { $headerParts = explode(' ', $line); $this->currentFile->setIndex($headerParts[1]); } protected function mergeIndex(string $line, array $context): void { $this->currentFile->setIndex($context[2]); } protected function fromFile(string $line, array $context): void { $this->currentFile->setFrom(trim($line, '- ')); } protected function toFile(string $line, array $context): void { $this->currentFile->setTo(trim($line, '+ ')); } protected function hunk(string $line, array $context): void { if ($this->currentHunk) { $this->currentFile->addHunk($this->currentHunk); } $oldStart = (int) ($context[2] ?? 0); $oldCount = (int) ($context[3] ?? 0); $newStart = (int) ($context[5] ?? 0); $newCount = (int) ($context[6] ?? 0); $this->oldCounter = $oldStart; $this->newCounter = $newStart; $this->deletedLines = 0; $this->addedLines = 0; $this->currentHunk = new Hunk($line, $oldStart, $oldCount, $newStart, $newCount); } protected function deletedLine(string $line, array $context): void { $oldNumber = $this->oldCounter + $this->deletedLines; $newNumber = $this->newCounter; $this->currentHunk->addLine(new Line($line, Line::TYPE_DELETE, $oldNumber, $newNumber)); $this->currentFile->increaseDeletions(); $this->deletedLines++; } protected function addedLine(string $line, array $context): void { $oldNumber = $this->oldCounter; $newNumber = $this->newCounter + $this->addedLines; $this->currentHunk->addLine(new Line($line, Line::TYPE_ADD, $oldNumber, $newNumber)); $this->currentFile->increaseAdditions(); $this->addedLines++; } protected function line(string $line): void { if (!$this->currentHunk || !$this->currentFile) { return; } $oldNumber = $this->oldCounter + $this->deletedLines; $newNumber = $this->newCounter + $this->addedLines; $this->currentHunk->addLine(new Line($line, Line::TYPE_NO_CHANGE, $oldNumber, $newNumber)); $this->oldCounter++; $this->newCounter++; } protected function clearAccumulator(): void { if ($this->currentFile) { if ($this->currentHunk) { $this->currentFile->addHunk($this->currentHunk); } $this->files[] = $this->currentFile; } $this->currentFile = $this->currentHunk = null; } }