Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git
git/GitDiff.php
$vDiffOld = new VirtualDiffFile( $path, $oldContent );
$vDiffNew = new VirtualDiffFile( $path, $newContent );
-
- $isBinary = ($newSha !== '' && $vDiffNew->isBinary()) ||
- ($newSha === '' && $oldSha !== '' && $vDiffOld->isBinary());
+ $isBinary = ($newSha !== '' && $vDiffNew->isBinary()) ||
+ ($newSha === '' && $oldSha !== '' && $vDiffOld->isBinary());
$result = [
$oldLines = explode( "\n", str_replace( "\r\n", "\n", $old ) );
$newLines = explode( "\n", str_replace( "\r\n", "\n", $new ) );
-
- unset( $old, $new );
-
- $m = count( $oldLines );
- $n = count( $newLines );
- $start = 0;
- $end = 0;
+ $m = count( $oldLines );
+ $n = count( $newLines );
+ $start = 0;
+ $end = 0;
while( $start < $m && $start < $n &&
$oldSlice = array_slice( $oldLines, $start, $m - $start - $end );
$newSlice = array_slice( $newLines, $start, $n - $start - $end );
- $result = [];
-
- unset( $oldLines, $newLines );
-
$countOld = count( $oldSlice );
$countNew = count( $newSlice );
$limit = 100000;
+ $result = [];
- if( ( $countOld * $countNew ) > $limit ) {
- error_log( "Diff complexity too high: $countOld * $countNew > $limit" );
- $result = [[ 't' => 'gap' ]];
+ if( ($countOld * $countNew) > $limit ) {
+ $result = $this->buildFallbackDiff( $oldSlice, $newSlice, $start );
} else {
$ops = $this->computeLCS( $oldSlice, $newSlice );
- $stream = $this->buildDiffStream(
- $ops,
- $oldSlice,
- $start,
- $m,
- $end
- );
+ $stream = $this->buildDiffStream( $ops, $start );
$result = $this->formatDiffOutput( $stream );
}
return $result;
}
- private function buildDiffStream(
- array $ops,
- array $oldSlice,
- int $start,
- int $m,
- int $end
+ private function buildFallbackDiff(
+ array $old,
+ array $new,
+ int $offset
): array {
+ $stream = [];
+ $currO = $offset + 1;
+ $currN = $offset + 1;
+
+ foreach( $old as $line ) {
+ $stream[] = [ 't' => '-', 'l' => $line, 'no' => $currO++, 'nn' => null ];
+ }
+
+ foreach( $new as $line ) {
+ $stream[] = [ 't' => '+', 'l' => $line, 'no' => null, 'nn' => $currN++ ];
+ }
+
+ return $stream;
+ }
+
+ private function buildDiffStream( array $ops, int $start ): array {
$stream = [];
$currO = $start + 1;
$currN = $start + 1;
foreach( $ops as $op ) {
- if( $op['t'] === ' ' ) {
- $stream[] = [
- 't' => ' ', 'l' => $op['l'], 'no' => $currO++, 'nn' => $currN++
- ];
- } elseif( $op['t'] === '-' ) {
- $stream[] = [
- 't' => '-', 'l' => $op['l'], 'no' => $currO++, 'nn' => null
- ];
- } elseif( $op['t'] === '+' ) {
- $stream[] = [
- 't' => '+', 'l' => $op['l'], 'no' => null, 'nn' => $currN++
- ];
- }
+ $stream[] = [
+ 't' => $op['t'],
+ 'l' => $op['l'],
+ 'no' => $op['t'] === '+' ? null : $currO++,
+ 'nn' => $op['t'] === '-' ? null : $currN++
+ ];
}
for( $i = 0; $i < $n; $i++ ) {
if( $stream[$i]['t'] !== ' ' ) {
- $start = max( 0, $i - $context );
- $end = min( $n - 1, $i + $context );
+ $low = max( 0, $i - $context );
+ $high = min( $n - 1, $i + $context );
- for( $j = $start; $j <= $end; $j++ ) {
+ for( $j = $low; $j <= $high; $j++ ) {
$keep[$j] = true;
}
$i--;
$j--;
- } elseif( $j > 0 &&
- ($i === 0 || $c[$i][$j - 1] >= $c[$i - 1][$j]) ) {
+ } elseif( $j > 0 && ($i === 0 || $c[$i][$j - 1] >= $c[$i - 1][$j]) ) {
$diff[] = [ 't' => '+', 'l' => $new[$j - 1] ];
$j--;
} elseif( $i > 0 && ($j === 0 || $c[$i][$j - 1] < $c[$i - 1][$j]) ) {
$diff[] = [ 't' => '-', 'l' => $old[$i - 1] ];
$i--;
}
}
return array_reverse( $diff );
- }
-}
-
-class VirtualDiffFile extends File {
- public function __construct( string $name, string $content ) {
- parent::__construct(
- $name,
- '',
- '100644',
- 0,
- strlen( $content ),
- $content
- );
}
}

Adds fallback mechanism for large gaps in diffs

Author Dave Jarvis <email>
Date 2026-02-18 17:22:35 GMT-0800
Commit 644dbda513ca85ffc8c7b5509579d517b26ba506
Parent f3507ba
Delta 40 lines added, 61 lines removed, 21-line decrease