-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdiff.php
128 lines (121 loc) · 5.62 KB
/
diff.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
<?php
# +--------------------------------------------------------------------+
# | phpEasyVCS |
# | The file-based version control system |
# +--------------------------------------------------------------------+
# | Copyright (c) 2011 Martin Vlcek |
# | License: GPLv3 (http://www.gnu.org/licenses/gpl-3.0.html) |
# +--------------------------------------------------------------------+
require_once('inc/basic.php');
require_once('inc/template.php');
$dir = sanitizeDir($_GET['dir']);
$name = sanitizeName($_GET['name']);
$fromVersion = (int) $_GET['from'];
$toVersion = (int) $_GET['to'];
$vcs = new FileVCS(DATAPATH, @$_GET['tag'], getUserName(), isReadOnly());
$tag = $vcs->getTag();
$tagname = $tag && $tag->name ? $tag->name : ($tag ? $_GET['tag'] : null);
$fromFile = $vcs->getEntry($dir, $name, $fromVersion);
$toFile = $vcs->getEntry($dir, $name, $toVersion);
/**
* Paul's Simple Diff Algorithm v 0.1
* (C) Paul Butler 2007 <http://www.paulbutler.org/>
* May be used and distributed under the zlib/libpng license.
*/
function diff($old, $new) {
$maxlen = 0;
foreach($old as $oindex => $ovalue) {
$nkeys = array_keys($new, $ovalue);
foreach($nkeys as $nindex) {
$matrix[$oindex][$nindex] = isset($matrix[$oindex - 1][$nindex - 1]) ?
$matrix[$oindex - 1][$nindex - 1] + 1 : 1;
if($matrix[$oindex][$nindex] > $maxlen) {
$maxlen = $matrix[$oindex][$nindex];
$omax = $oindex + 1 - $maxlen;
$nmax = $nindex + 1 - $maxlen;
}
}
}
if($maxlen == 0) return array(array('d'=>$old, 'i'=>$new));
return array_merge(
diff(array_slice($old, 0, $omax), array_slice($new, 0, $nmax)),
array_slice($new, $nmax, $maxlen),
diff(array_slice($old, $omax + $maxlen), array_slice($new, $nmax + $maxlen)));
}
function htmlDiff($old, $new) {
preg_match_all('/\p{L}+|./',$old,$matches_old,PREG_PATTERN_ORDER);
preg_match_all('/\p{L}+|./',$new,$matches_new,PREG_PATTERN_ORDER);
$diff = diff($matches_old[0], $matches_new[0]);
foreach($diff as $k){
if(is_array($k))
$ret .= (!empty($k['d'])?"<del>".htmlspecialchars(implode('',$k['d']))."</del>":'').
(!empty($k['i'])?"<ins>".htmlspecialchars(implode('',$k['i']))."</ins>":'');
else $ret .= htmlspecialchars($k);
}
return $ret;
}
if (!$fromFile || !$toFile) {
header("HTTP/1.0 404 Not Found");
} else {
chdir (dirname(__FILE__) . "/inc");
require_once("Text/Diff.php");
$diffable = preg_match('@^(text)/@',$toFile->mimetype);
$icon = Filetype::getIcon($toFile->ext).'.png';
template_header();
?>
<ul class="actions">
<li><a href="<?php echo 'versions.php?'.($tagname ? 'tag='.urlencode($tagname).'&' : '').'dir='.urlencode($dir).'&name='.urlencode($name); ?>">Show history</a></li>
<li><a href="<?php echo 'browse.php?'.($tagname ? 'tag='.urlencode($tagname).'&' : '').'dir='.urlencode($dir); ?>">Back to directory</a></li>
</ul>
<h2>
Differences of <img src="images/<?php echo $icon; ?>" alt=""/>
<a href="<?php echo 'browse.php?'.($tagname ? 'tag='.urlencode($tagname).'&' : '').'dir='.urlencode($dir); ?>">/<?php echo htmlspecialchars(substr($dir,0,-1)); ?></a><?php echo ($dir ? '/' : '').htmlspecialchars($name); ?>,
versions <?php echo $fromVersion; ?> <span class="date">(<?php echo timestamp2string($fromFile->date); ?>)</span>
and <?php echo $toVersion; ?> <span class="date">(<?php echo timestamp2string($toFile->date); ?>)</date>
</h2>
<?php
if ($diffable) {
$from_lines = file(DATAPATH.$fromFile->_content);
$to_lines = file(DATAPATH.$toFile->_content);
$textdiff = new Text_Diff('native', $from_lines, $to_lines);
$edits = $textdiff->getDiff();
$text = '';
foreach ($edits as $edit) {
if (is_a($edit, 'Text_Diff_Op_delete')) {
foreach ($edit->orig as $line) $text .= "<del>".htmlspecialchars($line)."\r\n</del>";
} else if (is_a($edit, 'Text_Diff_Op_add')) {
foreach ($edit->final as $line) $text .= "<ins>".htmlspecialchars($line)."\r\n</ins>";
} else if (is_a($edit, 'Text_Diff_Op_change')) {
$count = min(count($edit->orig),count($edit->final));
for ($i=0; $i<$count; $i++) {
$line = htmlDiff($edit->orig[$i],$edit->final[$i]);
if (preg_match('/^<del>[^<]*<\/del>$|^<ins>[^<]*<\/ins>$/i', $line)) {
$text .= substr($line,0,strlen($line)-6)."\r\n".substr($line,strlen($line)-6);
} else {
$text .= "<em>".$line."\r\n</em>";
}
}
if (count($edit->orig) > $count) {
foreach (array_slice($edit->orig,$count) as $line) $text .= "<del>".htmlspecialchars($line)."\r\n</del>";
}
if (count($edit->final) > $count) {
foreach (array_slice($edit->final,$count) as $line) $text .= "<ins>".htmlspecialchars($line)."\r\n</ins>";
}
} else {
foreach ($edit->orig as $line) $text .= htmlspecialchars($line)."\r\n";
}
}
// debug output
//echo "<pre>".htmlspecialchars(implode("",$from_lines))."</pre>\r\n";
//echo "<pre>".htmlspecialchars(implode("",$to_lines))."</pre>\r\n";
//echo "<pre>".htmlspecialchars(print_r($edits,true))."</pre>\r\n";
?>
<pre class="prettyprint linenums"><?php echo $text; ?></pre>
<?php
} else {
?>
<p>Differences can not be displayed.</p>
<?php
}
template_footer();
}