Rev Author Line No. Line
185 miho 1 <?php
2 # vim:et:ts=3:sts=3:sw=3:fdm=marker:
3  
4 // WebSVN - Subversion repository viewing via the web using PHP
5 // Copyright © 2004-2006 Tim Armes, Matt Sicker
6 //
7 // This program is free software; you can redistribute it and/or modify
8 // it under the terms of the GNU General Public License as published by
9 // the Free Software Foundation; either version 2 of the License, or
10 // (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful,
13 // but WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 // GNU General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 //
21 // --
22 //
23 // diff.php
24 //
25 // Show the differences between 2 revisions of a file.
26 //
27  
28 require_once("include/setup.inc");
29 require_once("include/svnlook.inc");
30 require_once("include/utils.inc");
31 require_once("include/template.inc");
32  
33 $context = 5;
34  
35 $vars["action"] = $lang["DIFF"];
36 $all = (@$_REQUEST["all"] == 1)?1:0;
37  
38 // Make sure that we have a repository
39 if (!isset($rep))
40 {
41 echo $lang["NOREP"];
42 exit;
43 }
44  
45 $svnrep = new SVNRepository($rep);
46  
47 // If there's no revision info, go to the lastest revision for this path
48 $history = $svnrep->getLog($path, "", "", true);
49 $youngest = $history->entries[0]->rev;
50  
51 if (empty($rev))
52 $rev = $youngest;
53  
54 $history = $svnrep->getLog($path, $rev);
55  
56 if ($path{0} != "/")
57 $ppath = "/".$path;
58 else
59 $ppath = $path;
60  
61 $prevrev = @$history->entries[1]->rev;
62  
63 $vars["repname"] = $rep->getDisplayName();
64 $vars["rev"] = $rev;
65 $vars["path"] = $ppath;
66 $vars["prevrev"] = $prevrev;
67  
68 $vars["rev1"] = $history->entries[0]->rev;
69 $vars["rev2"] = $prevrev;
70  
71 createDirLinks($rep, $ppath, $rev, $showchanged);
72  
73 $listing = array();
74  
75 if ($prevrev)
76 {
77 $url = $config->getURL($rep, $path, "diff");
78  
79 if (!$all)
80 {
81 $vars["showalllink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=1\">${lang["SHOWENTIREFILE"]}</a>";
82 $vars["showcompactlink"] = "";
83 }
84 else
85 {
86 $vars["showcompactlink"] = "<a href=\"${url}rev=$rev&amp;sc=$showchanged&amp;all=0\">${lang["SHOWCOMPACT"]}</a>";
87 $vars["showalllink"] = "";
88 }
89  
90 // Get the contents of the two files
91 $newtname = tempnam("temp", "");
92 $new = $svnrep->getFileContents($history->entries[0]->path, $newtname, $history->entries[0]->rev, "", true);
93  
94 $oldtname = tempnam("temp", "");
95 $old = $svnrep->getFileContents($history->entries[1]->path, $oldtname, $history->entries[1]->rev, "", true);
96  
97 $ent = true;
98 $extension = strrchr(basename($path), ".");
99 if (($extension && isset($extEnscript[$extension]) && ('php' == $extEnscript[$extension])) || ($config->useEnscript))
100 $ent = false;
101  
102 $file1cache = array();
103  
104 if ($all)
105 $context = 1; // Setting the context to 0 makes diff generate the wrong line numbers!
106  
107 // Open a pipe to the diff command with $context lines of context
108  
109 $cmd = quoteCommand($config->diff." --ignore-all-space -U $context $oldtname $newtname", false);
110  
111 if ($all)
112 {
113 $ofile = fopen($oldtname, "r");
114 $nfile = fopen($newtname, "r");
115 }
116  
117 if ($diff = popen($cmd, "r"))
118 {
119 // Ignore the 3 header lines
120 $line = fgets($diff);
121 $line = fgets($diff);
122  
123 // Get the first real line
124 $line = fgets($diff);
125  
126 $index = 0;
127 $listing = array();
128  
129 $curoline = 1;
130 $curnline = 1;
131  
132 while (!feof($diff))
133 {
134 // Get the first line of this range
135 sscanf($line, "@@ -%d", $oline);
136  
137 $line = substr($line, strpos($line, "+"));
138 sscanf($line, "+%d", $nline);
139  
140 if ($all)
141 {
142 while ($curoline < $oline || $curnline < $nline)
143 {
144 $listing[$index]["rev1diffclass"] = "diff";
145 $listing[$index]["rev2diffclass"] = "diff";
146  
147 if ($curoline < $oline)
148 {
149 $nl = fgets($ofile);
150  
151 if ($ent)
152 $line = replaceEntities(rtrim($nl), $rep);
153 else
154 $line = rtrim($nl);
155  
156 $listing[$index]["rev1line"] = hardspace($line);
157  
158 $curoline++;
159 }
160 else
161 $listing[$index]["rev1line"] = "&nbsp;";
162  
163 if ($curnline < $nline)
164 {
165 $nl = fgets($nfile);
166  
167 if ($ent)
168 $line = replaceEntities(rtrim($nl), $rep);
169 else
170 $line = rtrim($nl);
171  
172 $listing[$index]["rev2line"] = hardspace($line);
173 $curnline++;
174 }
175 else
176 $listing[$index]["rev2line"] = "&nbsp;";
177  
178 $listing[$index]["rev1lineno"] = 0;
179 $listing[$index]["rev2lineno"] = 0;
180  
181 $index++;
182 }
183 }
184 else
185 {
186 // Output the line numbers
187 $listing[$index]["rev1lineno"] = "$oline";
188 $listing[$index]["rev2lineno"] = "$nline";
189 $index++;
190 }
191  
192 $fin = false;
193 while (!feof($diff) && !$fin)
194 {
195 $listing[$index]["rev1lineno"] = 0;
196 $listing[$index]["rev2lineno"] = 0;
197  
198 $line = fgets($diff);
199 if (!strncmp($line, "@@", 2))
200 {
201 $fin = true;
202 }
203 else
204 {
205 $mod = $line{0};
206  
207 if ($ent)
208 $line = replaceEntities(rtrim(substr($line, 1)), $rep);
209 else
210 $line = rtrim(substr($line, 1));
211  
212 $listing[$index]["rev1line"] = hardspace($line);
213  
214 $text = hardspace($line);
215 if ($text == "") $text = "&nbsp;";
216  
217 switch ($mod)
218 {
219 case "-":
220 $listing[$index]["rev1diffclass"] = "diffdeleted";
221 $listing[$index]["rev2diffclass"] = "diff";
222  
223 $listing[$index]["rev1line"] = $text;
224 $listing[$index]["rev2line"] = "&nbsp;";
225  
226 if ($all)
227 {
228 fgets($ofile);
229 $curoline++;
230 }
231  
232 break;
233  
234 case "+":
235  
236 // Try to mark "changed" line sensibly
237 if (!empty($listing[$index-1]) && empty($listing[$index-1]["rev1lineno"]) && @$listing[$index-1]["rev1diffclass"] == "diffdeleted" && @$listing[$index-1]["rev2diffclass"] == "diff")
238 {
239 $i = $index - 1;
240 while (!empty($listing[$i-1]) && empty($listing[$i-1]["rev1lineno"]) && $listing[$i-1]["rev1diffclass"] == "diffdeleted" && $listing[$i-1]["rev2diffclass"] == "diff")
241 $i--;
242  
243 $listing[$i]["rev1diffclass"] = "diffchanged";
244 $listing[$i]["rev2diffclass"] = "diffchanged";
245 $listing[$i]["rev2line"] = $text;
246  
247 if ($all)
248 {
249 fgets($nfile);
250 $curnline++;
251 }
252  
253 // Don't increment the current index count
254 $index--;
255 }
256 else
257 {
258 $listing[$index]["rev1diffclass"] = "diff";
259 $listing[$index]["rev2diffclass"] = "diffadded";
260  
261 $listing[$index]["rev1line"] = "&nbsp;";
262 $listing[$index]["rev2line"] = $text;
263  
264 if ($all)
265 {
266 fgets($nfile);
267 $curnline++;
268 }
269 }
270 break;
271  
272 default:
273 $listing[$index]["rev1diffclass"] = "diff";
274 $listing[$index]["rev2diffclass"] = "diff";
275  
276 $listing[$index]["rev1line"] = $text;
277 $listing[$index]["rev2line"] = $text;
278  
279 if ($all)
280 {
281 fgets($ofile);
282 fgets($nfile);
283 $curoline++;
284 $curnline++;
285 }
286  
287 break;
288 }
289 }
290  
291 if (!$fin)
292 $index++;
293 }
294 }
295  
296 // Output the rest of the files
297 if ($all)
298 {
299 while (!feof($ofile) || !feof($nfile))
300 {
301 $listing[$index]["rev1diffclass"] = "diff";
302 $listing[$index]["rev2diffclass"] = "diff";
303  
304 if ($ent)
305 $line = replaceEntities(rtrim(fgets($ofile)), $rep);
306 else
307 $line = rtrim(fgets($ofile));
308  
309 if (!feof($ofile))
310 $listing[$index]["rev1line"] = hardspace($line);
311 else
312 $listing[$index]["rev1line"] = "&nbsp;";
313  
314 if ($ent)
315 $line = replaceEntities(rtrim(fgets($nfile)), $rep);
316 else
317 $line = rtrim(fgets($nfile));
318  
319 if (!feof($nfile))
320 $listing[$index]["rev2line"] = hardspace($line);
321 else
322 $listing[$index]["rev2line"] = "&nbsp;";
323  
324 $listing[$index]["rev1lineno"] = 0;
325 $listing[$index]["rev2lineno"] = 0;
326  
327 $index++;
328 }
329 }
330  
331 pclose($diff);
332 }
333  
334 if ($all)
335 {
336 fclose($ofile);
337 fclose($nfile);
338 }
339  
340 // Remove our temporary files
341 unlink($oldtname);
342 unlink($newtname);
343 }
344 else
345 {
346 $vars["noprev"] = 1;
347 }
348  
349 $vars["version"] = $version;
350  
351 if (!$rep->hasReadAccess($path, false))
352 $vars["noaccess"] = true;
353  
354 parseTemplate($rep->getTemplatePath()."header.tmpl", $vars, $listing);
355 parseTemplate($rep->getTemplatePath()."diff.tmpl", $vars, $listing);
356 parseTemplate($rep->getTemplatePath()."footer.tmpl", $vars, $listing);
357  
358 ?>