<?php# vim:et:ts=3:sts=3:sw=3:fdm=marker:// WebSVN - Subversion repository viewing via the web using PHP// Copyright © 2004-2006 Tim Armes, Matt Sicker//// This program is free software; you can redistribute it and/or modify// it under the terms of the GNU General Public License as published by// the Free Software Foundation; either version 2 of the License, or// (at your option) any later version.//// This program is distributed in the hope that it will be useful,// but WITHOUT ANY WARRANTY; without even the implied warranty of// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the// GNU General Public License for more details.//// You should have received a copy of the GNU General Public License// along with this program; if not, write to the Free Software// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA//// --//// diff.php//// Show the differences between 2 revisions of a file.//require_once("include/setup.inc");require_once("include/svnlook.inc");require_once("include/utils.inc");require_once("include/template.inc");$context = 5;$vars["action"] = $lang["DIFF"];$all = (@$_REQUEST["all"] == 1)?1:0;// Make sure that we have a repositoryif (!isset($rep)){echo $lang["NOREP"];exit;}$svnrep = new SVNRepository($rep);// If there's no revision info, go to the lastest revision for this path$history = $svnrep->getLog($path, "", "", true);$youngest = $history->entries[0]->rev;if (empty($rev))$rev = $youngest;$history = $svnrep->getLog($path, $rev);if ($path{0} != "/")$ppath = "/".$path;else$ppath = $path;$prevrev = @$history->entries[1]->rev;$vars["repname"] = $rep->getDisplayName();$vars["rev"] = $rev;$vars["path"] = $ppath;$vars["prevrev"] = $prevrev;$vars["rev1"] = $history->entries[0]->rev;$vars["rev2"] = $prevrev;createDirLinks($rep, $ppath, $rev, $showchanged);$listing = array();if ($prevrev){$url = $config->getURL($rep, $path, "diff");if (!$all){$vars["showalllink"] = "<a href=\"${url}rev=$rev&sc=$showchanged&all=1\">${lang["SHOWENTIREFILE"]}</a>";$vars["showcompactlink"] = "";}else{$vars["showcompactlink"] = "<a href=\"${url}rev=$rev&sc=$showchanged&all=0\">${lang["SHOWCOMPACT"]}</a>";$vars["showalllink"] = "";}// Get the contents of the two files$newtname = tempnam("temp", "");$new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true);$oldtname = tempnam("temp", "");$old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true);$ent = true;$extension = strrchr(basename($path), ".");if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))$ent = false;$file1cache = array();if ($all)$context = 1; // Setting the context to 0 makes diff generate the wrong line numbers!// Open a pipe to the diff command with $context lines of context$cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false);if ($all){$ofile = fopen($oldtname, "r");$nfile = fopen($newtname, "r");}if ($diff = popen($cmd, "r")){// Ignore the 3 header lines$line = fgets($diff);$line = fgets($diff);// Get the first real line$line = fgets($diff);$index = 0;$listing = array();$curoline = 1;$curnline = 1;while (!feof($diff)){// Get the first line of this rangesscanf($line, "@@ -%d", $oline);$line = substr($line, strpos($line, "+"));sscanf($line, "+%d", $nline);if ($all){while ($curoline < $oline || $curnline < $nline){$listing[$index]["rev1diffclass"] = "diff";$listing[$index]["rev2diffclass"] = "diff";if ($curoline < $oline){$nl = fgets($ofile);if ($ent)$line = replaceEntities(rtrim($nl), $rep);else$line = rtrim($nl);$listing[$index]["rev1line"] = hardspace($line);$curoline++;}else$listing[$index]["rev1line"] = " ";if ($curnline < $nline){$nl = fgets($nfile);if ($ent)$line = replaceEntities(rtrim($nl), $rep);else$line = rtrim($nl);$listing[$index]["rev2line"] = hardspace($line);$curnline++;}else$listing[$index]["rev2line"] = " ";$listing[$index]["rev1lineno"] = 0;$listing[$index]["rev2lineno"] = 0;$index++;}}else{// Output the line numbers$listing[$index]["rev1lineno"] = "$oline";$listing[$index]["rev2lineno"] = "$nline";$index++;}$fin = false;while (!feof($diff) && !$fin){$listing[$index]["rev1lineno"] = 0;$listing[$index]["rev2lineno"] = 0;$line = fgets($diff);if (!strncmp($line, "@@", 2)){$fin = true;}else{$mod = $line{0};if ($ent)$line = replaceEntities(rtrim(substr($line, 1)), $rep);else$line = rtrim(substr($line, 1));$listing[$index]["rev1line"] = hardspace($line);$text = hardspace($line);if ($text == "") $text = " ";switch ($mod){case "-":$listing[$index]["rev1diffclass"] = "diffdeleted";$listing[$index]["rev2diffclass"] = "diff";$listing[$index]["rev1line"] = $text;$listing[$index]["rev2line"] = " ";if ($all){fgets($ofile);$curoline++;}break;case "+":// Try to mark "changed" line sensiblyif (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff"){$i = $index - 1;while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff")$i--;$listing[$i]["rev1diffclass"] = "diffchanged";$listing[$i]["rev2diffclass"] = "diffchanged";$listing[$i]["rev2line"] = $text;if ($all){fgets($nfile);$curnline++;}// Don't increment the current index count$index--;}else{$listing[$index]["rev1diffclass"] = "diff";$listing[$index]["rev2diffclass"] = "diffadded";$listing[$index]["rev1line"] = " ";$listing[$index]["rev2line"] = $text;if ($all){fgets($nfile);$curnline++;}}break;default:$listing[$index]["rev1diffclass"] = "diff";$listing[$index]["rev2diffclass"] = "diff";$listing[$index]["rev1line"] = $text;$listing[$index]["rev2line"] = $text;if ($all){fgets($ofile);fgets($nfile);$curoline++;$curnline++;}break;}}if (!$fin)$index++;}}// Output the rest of the filesif ($all){while (!feof($ofile) || !feof($nfile)){$listing[$index]["rev1diffclass"] = "diff";$listing[$index]["rev2diffclass"] = "diff";if ($ent)$line = replaceEntities(rtrim(fgets($ofile)), $rep);else$line = rtrim(fgets($ofile));if (!feof($ofile))$listing[$index]["rev1line"] = hardspace($line);else$listing[$index]["rev1line"] = " ";if ($ent)$line = replaceEntities(rtrim(fgets($nfile)), $rep);else$line = rtrim(fgets($nfile));if (!feof($nfile))$listing[$index]["rev2line"] = hardspace($line);else$listing[$index]["rev2line"] = " ";$listing[$index]["rev1lineno"] = 0;$listing[$index]["rev2lineno"] = 0;$index++;}}pclose($diff);}if ($all){fclose($ofile);fclose($nfile);}// Remove our temporary filesunlink($oldtname);unlink($newtname);}else{$vars["noprev"] = 1;}$vars["version"] = $version;if (!$rep->hasReadAccess($path, false))$vars["noaccess"] = true;parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing);parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);?>