Dave Jarvis' Repositories

git clone https://repo.autonoma.ca/repo/treetrek.git

Uses File instance to reduce duplication

Author Dave Jarvis <email>
Date 2026-02-20 17:13:52 GMT-0800
Commit 85cb79ea30d368a63cec35fa16ed2f8ff5cfcf47
Parent d9fb252
Delta 80 lines added, 85 lines removed, 5-line decrease
File.php
}
+ public function isEmpty(): bool {
+ return $this->size === 0;
+ }
+
public function compare( File $other ): int {
return $this->isDir !== $other->isDir
git/Git.php
private function findTreeEntry( string $treeSha, string $name ): array {
$data = $this->read( $treeSha );
- $pos = 0;
- $len = strlen( $data );
$entry = [ 'sha' => '', 'mode' => '' ];
-
- while( $pos < $len ) {
- $space = strpos( $data, ' ', $pos );
- $eos = strpos( $data, "\0", $space );
- if( $space === false || $eos === false ) {
- break;
- }
+ $this->parseTreeData(
+ $data,
+ function( $file, $n, $sha, $mode ) use ( $name, &$entry ) {
+ if( $file->isName( $name ) ) {
+ $entry = [ 'sha' => $sha, 'mode' => $mode ];
- if( substr( $data, $space + 1, $eos - $space - 1 ) === $name ) {
- $entry = [
- 'sha' => bin2hex( substr( $data, $eos + 1, 20 ) ),
- 'mode' => substr( $data, $pos, $space - $pos )
- ];
- break;
+ return false;
+ }
}
-
- $pos = $eos + 21;
- }
+ );
return $entry;
private function processTree( string $data, callable $callback ): void {
+ $this->parseTreeData(
+ $data,
+ function( $file, $n, $s, $m ) use ( $callback ) {
+ $callback( $file );
+ }
+ );
+ }
+
+ public function parseTreeData( string $data, callable $callback ): void {
$pos = 0;
$len = strlen( $data );
while( $pos < $len ) {
$space = strpos( $data, ' ', $pos );
$eos = strpos( $data, "\0", $space );
- $entry = null;
-
- if( $space !== false && $eos !== false && $eos + 21 <= $len ) {
- $mode = substr( $data, $pos, $space - $pos );
- $sha = bin2hex( substr( $data, $eos + 1, 20 ) );
- $dir = $mode === '40000' || $mode === '040000';
- $isSub = $mode === '160000';
- $entry = [
- 'file' => new File(
- substr( $data, $space + 1, $eos - $space - 1 ),
- $sha,
- $mode,
- 0,
- $dir || $isSub ? 0 : $this->getObjectSize( $sha ),
- $dir || $isSub ? '' : $this->peek( $sha )
- ),
- 'nextPosition' => $eos + 21
- ];
+ if( $space === false || $eos === false || $eos + 21 > $len ) {
+ break;
}
- if( $entry === null ) {
+ $mode = substr( $data, $pos, $space - $pos );
+ $name = substr( $data, $space + 1, $eos - $space - 1 );
+ $sha = bin2hex( substr( $data, $eos + 1, 20 ) );
+ $dir = $mode === '40000' || $mode === '040000';
+ $isSub = $mode === '160000';
+
+ $file = new File(
+ $name,
+ $sha,
+ $mode,
+ 0,
+ $dir || $isSub ? 0 : $this->getObjectSize( $sha ),
+ $dir || $isSub ? '' : $this->peek( $sha )
+ );
+
+ if( $callback( $file, $name, $sha, $mode ) === false ) {
break;
}
- $callback( $entry['file'] );
- $pos = $entry['nextPosition'];
+ $pos = $eos + 21;
}
}
git/GitDiff.php
if( !$old && $new ) {
- if( $new['is_dir'] ) {
+ if( $new['file']->isDir() ) {
yield from $this->diffTrees( '', $new['sha'], $currentPath );
} else {
- yield $this->createChange( 'A', $currentPath, '', $new['sha'] );
+ yield $this->createChange(
+ 'A',
+ $currentPath,
+ '',
+ $new['sha'],
+ null,
+ $new['file']
+ );
}
} elseif( !$new && $old ) {
- if( $old['is_dir'] ) {
+ if( $old['file']->isDir() ) {
yield from $this->diffTrees( $old['sha'], '', $currentPath );
} else {
- yield $this->createChange( 'D', $currentPath, $old['sha'], '' );
+ yield $this->createChange(
+ 'D',
+ $currentPath,
+ $old['sha'],
+ '',
+ $old['file'],
+ null
+ );
}
} elseif( $old && $new && $old['sha'] !== $new['sha'] ) {
- if( $old['is_dir'] && $new['is_dir'] ) {
+ if( $old['file']->isDir() && $new['file']->isDir() ) {
yield from $this->diffTrees(
$old['sha'],
$new['sha'],
$currentPath
);
- } elseif( !$old['is_dir'] && !$new['is_dir'] ) {
+ } elseif( !$old['file']->isDir() && !$new['file']->isDir() ) {
yield $this->createChange(
'M',
$currentPath,
$old['sha'],
- $new['sha']
+ $new['sha'],
+ $old['file'],
+ $new['file']
);
}
$data = $this->git->read( $sha );
$entries = [];
- $len = strlen( $data );
- $pos = 0;
-
- while( $pos < $len ) {
- $space = strpos( $data, ' ', $pos );
- $null = strpos( $data, "\0", $space );
- if( $space === false || $null === false ) {
- break;
+ $this->git->parseTreeData(
+ $data,
+ function( $file, $name, $hash, $mode ) use ( &$entries ) {
+ $entries[$name] = [
+ 'file' => $file,
+ 'sha' => $hash
+ ];
}
-
- $mode = substr( $data, $pos, $space - $pos );
- $name = substr( $data, $space + 1, $null - $space - 1 );
- $hash = bin2hex( substr( $data, $null + 1, 20 ) );
-
- $entries[$name] = [
- 'mode' => $mode,
- 'sha' => $hash,
- 'is_dir' => $mode === '40000' || $mode === '040000'
- ];
-
- $pos = $null + 21;
- }
+ );
return $entries;
}
private function createChange(
string $type,
string $path,
string $oldSha,
- string $newSha
+ string $newSha,
+ ?File $oldFile = null,
+ ?File $newFile = null
): array {
$oldSize = $oldSha !== '' ? $this->git->getObjectSize( $oldSha ) : 0;
$oldContent = $oldSha !== '' ? $this->git->read( $oldSha ) : '';
$newContent = $newSha !== '' ? $this->git->read( $newSha ) : '';
- $vDiffOld = new VirtualDiffFile( $path, $oldContent );
- $vDiffNew = new VirtualDiffFile( $path, $newContent );
+ $isBinary = false;
- $isBinary = ($newSha !== '' && $vDiffNew->isBinary()) ||
- ($newSha === '' && $oldSha !== '' && $vDiffOld->isBinary());
+ if( $newFile !== null ) {
+ $isBinary = $newFile->isBinary();
+ } elseif( $oldFile !== null ) {
+ $isBinary = $oldFile->isBinary();
+ }
$result = [
return array_reverse( $diff );
- }
-}
-
-class VirtualDiffFile extends File {
- public function __construct( string $name, string $content ) {
- parent::__construct(
- $name,
- '',
- '100644',
- 0,
- strlen( $content ),
- $content
- );
}
}