Rev Author Line No. Line
185 miho 1 <?php
2 // WebSVN - Subversion repository viewing via the web using PHP
4988 kaklik 3 // Copyright (C) 2004-2006 Tim Armes
185 miho 4 //
5 // This program is free software; you can redistribute it and/or modify
6 // it under the terms of the GNU General Public License as published by
7 // the Free Software Foundation; either version 2 of the License, or
8 // (at your option) any later version.
9 //
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
4988 kaklik 12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
185 miho 13 // GNU General Public License for more details.
14 //
15 // You should have received a copy of the GNU General Public License
16 // along with this program; if not, write to the Free Software
4988 kaklik 17 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
185 miho 18 //
19 // --
20 //
21 // diff.php
22 //
23 // Show the differences between 2 revisions of a file.
24 //
25  
4988 kaklik 26 require_once 'include/setup.php';
27 require_once 'include/svnlook.php';
28 require_once 'include/utils.php';
29 require_once 'include/template.php';
185 miho 30  
4988 kaklik 31 require_once 'include/diff_inc.php';
185 miho 32  
4988 kaklik 33 $vars['action'] = $lang['DIFF'];
34 $all = (@$_REQUEST['all'] == 1);
35 $ignoreWhitespace = $config->getIgnoreWhitespacesInDiff();
185 miho 36  
4988 kaklik 37 if (array_key_exists('ignorews', $_REQUEST))
38 {
39 $ignoreWhitespace = (bool)$_REQUEST['ignorews'];
40 }
41  
185 miho 42 // Make sure that we have a repository
4988 kaklik 43 if (!$rep)
185 miho 44 {
4988 kaklik 45 renderTemplate404('diff','NOREP');
185 miho 46 }
47  
48 $svnrep = new SVNRepository($rep);
49  
50 // If there's no revision info, go to the lastest revision for this path
4988 kaklik 51 $history = $svnrep->getLog($path, 'HEAD', 1, true, 2, ($path == '/') ? '' : $peg);
185 miho 52  
4988 kaklik 53 if (!$history)
54 {
55 unset($vars['error']);
56 $history = $svnrep->getLog($path, '', '', true, 2, ($path == '/') ? '' : $peg);
57 }
185 miho 58  
4988 kaklik 59 $youngest = ($history && isset($history->entries[0])) ? $history->entries[0]->rev : false;
185 miho 60  
4988 kaklik 61 if (empty($rev))
62 {
63 $rev = $youngest;
64 }
185 miho 65  
4988 kaklik 66 $history = $svnrep->getLog($path, $rev, 1, false, 2, $peg);
67  
68 if ($path[0] != '/')
69 {
70 $ppath = '/'.$path;
71 }
72 else
73 {
74 $ppath = $path;
75 }
76  
185 miho 77 $prevrev = @$history->entries[1]->rev;
78  
4988 kaklik 79 $vars['path'] = str_replace('%2F', '/', rawurlencode($ppath));
80 $vars['safepath'] = escape($ppath);
81 $vars['rev1'] = $rev;
82 $vars['rev2'] = $prevrev;
83 $vars['prevrev'] = $prevrev;
185 miho 84  
4988 kaklik 85 if (isset($history->entries[0]))
86 {
87 $vars['log'] = xml_entities($history->entries[0]->msg);
88 $vars['date'] = $history->entries[0]->date;
89 $vars['age'] = datetimeFormatDuration(time() - strtotime($history->entries[0]->date));
90 $vars['author'] = $history->entries[0]->author;
91 $vars['rev'] = $vars['rev1'] = $history->entries[0]->rev;
92 $vars['peg'] = $peg;
93 }
185 miho 94  
4988 kaklik 95 createPathLinks($rep, $ppath, $passrev, $peg);
96 $passRevString = createRevAndPegString($rev, $peg);
185 miho 97  
4988 kaklik 98 $passIgnoreWhitespace = '';
99 if ($ignoreWhitespace != $config->getIgnoreWhitespacesInDiff())
100 {
101 $passIgnoreWhitespace = '&amp;ignorews='.($ignoreWhitespace ? '1' : '0');
102 }
185 miho 103  
4988 kaklik 104 if ($rev != $youngest)
185 miho 105 {
4988 kaklik 106 $vars['goyoungesturl'] = $config->getURL($rep, $path, 'diff').createRevAndPegString('', $peg).$passIgnoreWhitespace;
107 $vars['goyoungestlink'] = '<a href="'.$vars['goyoungesturl'].'"'.($youngest ? ' title="'.$lang['REV'].' '.$youngest.'"' : '').'>'.$lang['GOYOUNGEST'].'</a>';
108 }
185 miho 109  
4988 kaklik 110 $revurl = $config->getURL($rep, $path, 'diff');
185 miho 111  
4988 kaklik 112 if ($rev < $youngest)
113 {
114 $history2 = $svnrep->getLog($path, $rev, $youngest, true, 2, $peg ? $peg : 'HEAD');
185 miho 115  
4988 kaklik 116 if (isset($history2->entries[1]))
117 {
118 $nextRev = $history2->entries[1]->rev;
119 if ($nextRev != $youngest)
120 {
121 $vars['nextrev'] = $nextRev;
122 $vars['nextrevurl'] = $revurl.createRevAndPegString($nextRev, $peg).$passIgnoreWhitespace;
123 }
124 }
185 miho 125  
4988 kaklik 126 unset($vars['error']);
127 }
185 miho 128  
4988 kaklik 129 if (isset($history->entries[1]))
130 {
131 $prevRev = $history->entries[1]->rev;
132 $prevPath = $history->entries[1]->path;
133 $vars['prevrev'] = $prevRev;
134 $vars['prevrevurl'] = $revurl.createRevAndPegString($prevRev, $peg).$passIgnoreWhitespace;
135 }
185 miho 136  
4988 kaklik 137 $vars['revurl'] = $config->getURL($rep, $path, 'revision').$passRevString;
138 $vars['revlink'] = '<a href="'.$vars['revurl'].'">'.$lang['LASTMOD'].'</a>';
185 miho 139  
4988 kaklik 140 $vars['logurl'] = $config->getURL($rep, $path, 'log').$passRevString;
141 $vars['loglink'] = '<a href="'.$vars['logurl'].'">'.$lang['VIEWLOG'].'</a>';
185 miho 142  
4988 kaklik 143 $vars['filedetailurl'] = $config->getURL($rep, $path, 'file').$passRevString;
144 $vars['filedetaillink'] = '<a href="'.$vars['filedetailurl'].'">'.$lang['FILEDETAIL'].'</a>';
185 miho 145  
4988 kaklik 146 $vars['blameurl'] = $config->getURL($rep, $path, 'blame').$passRevString;
147 $vars['blamelink'] = '<a href="'.$vars['blameurl'].'">'.$lang['BLAME'].'</a>';
185 miho 148  
4988 kaklik 149 if ($rep->isRssEnabled())
150 {
151 $vars['rssurl'] = $config->getURL($rep, $path, 'rss').createRevAndPegString('', $peg);
152 $vars['rsslink'] = '<a href="'.$vars['rssurl'].'">'.$lang['RSSFEED'].'</a>';
153 }
185 miho 154  
4988 kaklik 155 // Check for binary file type before diffing.
156 $svnMimeType = $svnrep->getProperty($path, 'svn:mime-type', $rev);
185 miho 157  
4988 kaklik 158 // If no previous revision exists, bail out before diffing
159 if (!$rep->getIgnoreSvnMimeTypes() && preg_match('~application/*~', $svnMimeType))
160 {
161 $vars['warning'] = 'Cannot display diff of binary file. (svn:mime-type = '.$svnMimeType.')';
185 miho 162  
4988 kaklik 163 }
164 else if (!$prevrev)
165 {
166 $vars['noprev'] = 1;
167 }
168 else
169 {
170 $diff = $config->getURL($rep, $path, 'diff').$passRevString;
185 miho 171  
4988 kaklik 172 if ($all)
173 {
174 $vars['showcompactlink'] = '<a href="'.$diff.$passIgnoreWhitespace.'">'.$lang['SHOWCOMPACT'].'</a>';
175 }
176 else
177 {
178 $vars['showalllink'] = '<a href="'.$diff.$passIgnoreWhitespace.'&amp;all=1'.'">'.$lang['SHOWENTIREFILE'].'</a>';
179 }
185 miho 180  
4988 kaklik 181 $passShowAll = ($all ? '&amp;all=1' : '');
182 $toggleIgnoreWhitespace = '';
185 miho 183  
4988 kaklik 184 if ($ignoreWhitespace == $config->getIgnoreWhitespacesInDiff())
185 {
186 $toggleIgnoreWhitespace = '&amp;ignorews='.($ignoreWhitespace ? '0' : '1');
187 }
185 miho 188  
4988 kaklik 189 if ($ignoreWhitespace)
190 {
191 $vars['regardwhitespacelink'] = '<a href="'.$diff.$passShowAll.$toggleIgnoreWhitespace.'">'.$lang['REGARDWHITESPACE'].'</a>';
192 }
193 else
194 {
195 $vars['ignorewhitespacelink'] = '<a href="'.$diff.$passShowAll.$toggleIgnoreWhitespace.'">'.$lang['IGNOREWHITESPACE'].'</a>';
196 }
185 miho 197  
4988 kaklik 198 // Get the contents of the two files
199 $newerFile = tempnamWithCheck($config->getTempDir(), '');
200 $newerFileHl = $newerFile.'highlight';
201 $normalNew = $svnrep->getFileContents($history->entries[0]->path, $newerFile, $history->entries[0]->rev, $peg, '', 'no');
202 $highlightedNew = $svnrep->getFileContents($history->entries[0]->path, $newerFileHl, $history->entries[0]->rev, $peg, '', 'line');
185 miho 203  
4988 kaklik 204 $olderFile = tempnamWithCheck($config->getTempDir(), '');
205 $olderFileHl = $olderFile.'highlight';
206 $normalOld = $svnrep->getFileContents($history->entries[0]->path, $olderFile, $history->entries[1]->rev, $peg, '', 'no');
207 $highlightedOld = $svnrep->getFileContents($history->entries[0]->path, $olderFileHl, $history->entries[1]->rev, $peg, '', 'line');
208 // TODO: Figured out why diffs across a move/rename are currently broken.
185 miho 209  
4988 kaklik 210 $highlighted = ($highlightedNew && $highlightedOld);
185 miho 211  
4988 kaklik 212 if ($highlighted)
213 {
214 $listing = do_diff($all, $ignoreWhitespace, $highlighted, $newerFile, $olderFile, $newerFileHl, $olderFileHl);
215 }
216 else
217 {
218 $listing = do_diff($all, $ignoreWhitespace, $highlighted, $newerFile, $olderFile, null, null);
219 }
220  
221 // Remove our temporary files
222 @unlink($newerFile);
223 @unlink($olderFile);
224 @unlink($newerFileHl);
225 @unlink($olderFileHl);
185 miho 226 }
4988 kaklik 227  
228 if (!$rep->hasReadAccess($path, false))
185 miho 229 {
4988 kaklik 230 $vars['error'] = $lang['NOACCESS'];
231 sendHeaderForbidden();
185 miho 232 }
233  
4988 kaklik 234 renderTemplate('diff');