<?php require_once __DIR__ . '/BasePage.php'; require_once __DIR__ . '/../git/GitDiff.php'; class ComparePage extends BasePage { private $currentRepo; private $git; private $newSha; private $oldSha; public function __construct( array $repositories, array $currentRepo, Git $git, string $newSha, string $oldSha ) { $title = $currentRepo['name'] . ' - Compare'; parent::__construct( $repositories, $title ); $this->currentRepo = $currentRepo; $this->git = $git; $this->newSha = $newSha; $this->oldSha = $oldSha; } public function render() { $this->renderLayout( function() { $shortNew = substr( $this->newSha, 0, 7 ); $shortOld = substr( $this->oldSha, 0, 7 ); $this->renderBreadcrumbs( $this->currentRepo, ["Compare $shortNew...$shortOld"] ); $differ = new GitDiff( $this->git ); $changes = $differ->diff( $this->oldSha, $this->newSha ); if( empty( $changes ) ) { echo '<div class="empty-state"><h3>No changes</h3>' . '<p>No differences.</p></div>'; } else { foreach( $changes as $change ) { $this->renderDiffFile( $change ); } } }, $this->currentRepo ); } private function renderDiffFile( array $change ) { $typeMap = [ 'A' => 'added', 'D' => 'deleted', 'M' => 'modified' ]; $statusClass = $typeMap[$change['type']] ?? 'modified'; $path = htmlspecialchars( $change['path'] ); echo '<div class="diff-file">'; echo '<div class="diff-header ' . $statusClass . '">'; echo '<span class="diff-status-icon">' . $change['type'] . '</span> '; echo $path; echo '</div>'; if( $change['is_binary'] ) { echo '<div class="diff-content binary">Binary file</div>'; } elseif( !empty( $change['hunks'] ) ) { echo '<div class="diff-content">'; echo '<table class="diff-table"><tbody>'; foreach( $change['hunks'] as $line ) { $this->renderDiffLine( $line ); } echo '</tbody></table>'; echo '</div>'; } echo '</div>'; } private function renderDiffLine( array $line ) { if( isset( $line['t'] ) && $line['t'] === 'gap' ) { echo '<tr class="diff-gap"><td colspan="3">...</td></tr>'; } else { $class = match( $line['t'] ) { '+' => 'diff-add', '-' => 'diff-del', default => '' }; echo '<tr class="' . $class . '">'; echo '<td class="diff-line-num">' . ($line['no'] ?? '') . '</td>'; echo '<td class="diff-line-num">' . ($line['nn'] ?? '') . '</td>'; echo '<td class="diff-code"><pre>' . htmlspecialchars( $line['l'] ?? '' ) . '</pre></td>'; echo '</tr>'; } } }