getLog($path, 'HEAD', 1, false, 2, ($path == '/') ? '' : $peg); if (!$history) { unset($vars['error']); $history = $svnrep->getLog($path, '', '', false, 2, ($path == '/') ? '' : $peg); if (!$history) { header('HTTP/1.x 404 Not Found', true, 404); $vars['error'] = $lang['NOPATH']; } } $youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : 0; $vars['youngestrev'] = $youngest; // TODO The "youngest" rev is often incorrect when both path and rev are specified. // If a path was last modified at rev M and the URL contains rev N, it uses rev N. // Unless otherwise specified, we get the log details of the latest change $lastChangedRev = ($rev) ? $rev : $youngest; if ($lastChangedRev != $youngest) { $history = $svnrep->getLog($path, $lastChangedRev, 1, false, 2, $peg); if (!$history) { header('HTTP/1.x 404 Not Found', true, 404); $vars['error'] = $lang['NOPATH']; } } if (empty($rev)) $rev = $lastChangedRev; // Generate links to newer and older revisions $revurl = $config->getURL($rep, $path, 'revision'); if ($rev < $youngest) { $vars['goyoungesturl'] = $config->getURL($rep, $path, 'revision'); $vars['goyoungestlink'] = ''.$lang['GOYOUNGEST'].''; $history2 = $svnrep->getLog($path, $rev, $youngest, false, 2, $peg); if (isset($history2->entries[1])) { $nextRev = $history2->entries[1]->rev; if ($nextRev != $youngest) { $vars['nextrev'] = $nextRev; $vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $path != '/' ? $peg ? $peg : $rev : ''); //echo 'NEXT='.$vars['nextrevurl'].'
'; } } unset($vars['error']); } if (isset($history->entries[1])) { $prevRev = $history->entries[1]->rev; $prevPath = $history->entries[1]->path; $vars['prevrev'] = $prevRev; $vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $path != '/' ? ($peg ? $peg : $rev) : ''); //echo 'PREV='.$vars['prevrevurl'].'
'; } // Save the entry from which we pull information for the current revision. $logEntry = (isset($history->entries[0])) ? $history->entries[0] : null; $bugtraq = new Bugtraq($rep, $svnrep, $ppath); $vars['action'] = ''; $vars['rev'] = $rev; $vars['peg'] = $peg; $vars['path'] = escape($ppath); if ($logEntry) { $vars['date'] = $logEntry->date; $vars['age'] = datetimeFormatDuration(time() - strtotime($logEntry->date)); $vars['author'] = $logEntry->author; $vars['log'] = nl2br($bugtraq->replaceIDs(create_anchors(xml_entities($logEntry->msg)))); } $isDir = @$_REQUEST['isdir'] == 1 || $path == '' || $path == '/'; $vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString.($isDir ? '&isdir=1' : ''); $vars['loglink'] = ''.$lang['VIEWLOG'].''; $dirPath = $isDir ? $path : dirname($path).'/'; $vars['directoryurl'] = $config->getURL($rep, $dirPath, 'dir').$passRevString.'#'.anchorForPath($dirPath); $vars['directorylink'] = ''.$lang['LISTING'].''; if ($path != $dirPath) { $vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString; $vars['filedetaillink'] = ''.$lang['FILEDETAIL'].''; $vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString; $vars['blamelink'] = ''.$lang['BLAME'].''; } if ($rep->isRssEnabled()) { $vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg); $vars['rsslink'] = ''.$lang['RSSFEED'].''; } $changes = $logEntry ? $logEntry->mods : array(); if (!is_array($changes)) { $changes = array(); } usort($changes, 'SVNLogEntry_compare'); $row = 0; $prevRevString = createRevAndPegString($rev - 1, $rev - 1); $thisRevString = createRevAndPegString($rev, $rev); foreach ($changes as $change) { $linkRevString = ($change->action == 'D') ? $prevRevString : $thisRevString; // NOTE: This is a hack (runs `svn info` on each path) to see if it's a file. // `svn log --verbose --xml` should really provide this info, but doesn't yet. $lastSeenRev = ($change->action == 'D') ? $rev - 1 : $rev; $isFile = $svnrep->isFile($change->path, $lastSeenRev, $lastSeenRev); if (!$isFile && $change->path != '/') { $change->path .= '/'; } $resourceExisted = $change->action == 'M' || $change->copyfrom; $listing[] = array( 'path' => $change->path, 'oldpath' => $change->copyfrom ? $change->copyfrom.' @ '.$change->copyrev : '', 'action' => $change->action, 'added' => $change->action == 'A', 'deleted' => $change->action == 'D', 'modified' => $change->action == 'M', 'detailurl' => $config->getURL($rep, $change->path, ($isFile ? 'file' : 'dir')).$linkRevString, // For deleted resources, the log link points to the previous revision. 'logurl' => $config->getURL($rep, $change->path, 'log').$linkRevString.($isFile ? '' : '&isdir=1'), 'diffurl' => $resourceExisted ? $config->getURL($rep, $change->path, 'diff').$linkRevString : '', 'blameurl' => $resourceExisted ? $config->getURL($rep, $change->path, 'blame').$linkRevString : '', 'rowparity' => $row, 'notinpath' => substr($change->path, 0, strlen($path)) != $path, ); $row = 1 - $row; } if (isset($prevRev)) { $vars['compareurl'] = $config->getURL($rep, '', 'comp').'compare[]='.urlencode($prevPath).'@'.$prevRev. '&compare[]='.urlencode($path).'@'.$rev; $vars['comparelink'] = ''.$lang['DIFFPREV'].''; } if (!$rep->hasReadAccess($path, true)) { $vars['error'] = $lang['NOACCESS']; checkSendingAuthHeader($rep); } $vars['restricted'] = !$rep->hasReadAccess($path, false); } else { header('HTTP/1.x 404 Not Found', true, 404); } renderTemplate('revision');