| | class Git { |
| | private const CHUNK_SIZE = 128; |
| | + |
| | private string $path; |
| | private string $objPath; |
| | |
| | private GitRefs $refs; |
| | private GitPacks $packs; |
| | |
| | - public function __construct(string $repoPath) { |
| | - $this->path = rtrim($repoPath, '/'); |
| | + public function __construct( string $repoPath ) { |
| | + $this->setRepository( $repoPath ); |
| | + } |
| | + |
| | + public function setRepository( $repoPath ) { |
| | + $this->path = rtrim( $repoPath, '/' ); |
| | $this->objPath = $this->path . '/objects'; |
| | - $this->refs = new GitRefs($this->path); |
| | - $this->packs = new GitPacks($this->objPath); |
| | + |
| | + $this->refs = new GitRefs( $this->path ); |
| | + $this->packs = new GitPacks( $this->objPath ); |
| | } |
| | |
| | - public function resolve(string $ref): string { |
| | - return $this->refs->resolve($ref); |
| | + public function resolve( string $ref ): string { |
| | + return $this->refs->resolve( $ref ); |
| | } |
| | |
| | public function getMainBranch(): array { |
| | return $this->refs->getMainBranch(); |
| | } |
| | |
| | - public function eachBranch(callable $cb): void { |
| | - $this->refs->scanRefs('refs/heads', $cb); |
| | + public function eachBranch( callable $cb ): void { |
| | + $this->refs->scanRefs( 'refs/heads', $cb ); |
| | } |
| | |
| | - public function eachTag(callable $cb): void { |
| | - $this->refs->scanRefs('refs/tags', $cb); |
| | + public function eachTag( callable $cb ): void { |
| | + $this->refs->scanRefs( 'refs/tags', $cb ); |
| | } |
| | |
| | - public function getObjectSize(string $sha): int { |
| | - $size = $this->packs->getSize($sha); |
| | - if ($size !== null) return $size; |
| | + public function getObjectSize( string $sha ): int { |
| | + $size = $this->packs->getSize( $sha ); |
| | + if( $size !== null ) return $size; |
| | |
| | - return $this->getLooseObjectSize($sha); |
| | + return $this->getLooseObjectSize( $sha ); |
| | } |
| | |
| | - public function read(string $sha): string { |
| | - $loosePath = $this->getLoosePath($sha); |
| | + public function read( string $sha ): string { |
| | + $loosePath = $this->getLoosePath( $sha ); |
| | |
| | - if (file_exists($loosePath)) { |
| | - $raw = file_get_contents($loosePath); |
| | - $inflated = $raw ? @gzuncompress($raw) : false; |
| | - return $inflated ? explode("\0", $inflated, 2)[1] : ''; |
| | + if( file_exists( $loosePath ) ) { |
| | + $raw = file_get_contents( $loosePath ); |
| | + $inflated = $raw ? @gzuncompress( $raw ) : false; |
| | + return $inflated ? explode( "\0", $inflated, 2 )[1] : ''; |
| | } |
| | |
| | - return $this->packs->read($sha) ?? ''; |
| | + return $this->packs->read( $sha ) ?? ''; |
| | } |
| | |
| | - public function stream(string $sha, callable $callback): void { |
| | - $data = $this->read($sha); |
| | - if ($data !== '') $callback($data); |
| | + public function stream( string $sha, callable $callback ): void { |
| | + $data = $this->read( $sha ); |
| | + if( $data !== '' ) $callback( $data ); |
| | } |
| | |
| | - public function history(string $ref, int $limit, callable $cb): void { |
| | - $curr = $this->resolve($ref); |
| | + public function history( string $ref, int $limit, callable $cb ): void { |
| | + $curr = $this->resolve( $ref ); |
| | $count = 0; |
| | |
| | - while ($curr !== '' && $count < $limit) { |
| | - $data = $this->read($curr); |
| | - if ($data === '') break; |
| | + while( $curr !== '' && $count < $limit ) { |
| | + $data = $this->read( $curr ); |
| | + if( $data === '' ) break; |
| | |
| | - $pos = strpos($data, "\n\n"); |
| | - $msg = ($pos !== false) ? substr($data, $pos + 2) : ''; |
| | - preg_match('/^author (.*) <(.*)> (\d+)/m', $data, $m); |
| | + $pos = strpos( $data, "\n\n" ); |
| | + $msg = ($pos !== false) ? substr( $data, $pos + 2 ) : ''; |
| | + preg_match( '/^author (.*) <(.*)> (\d+)/m', $data, $m ); |
| | |
| | - $cb((object)[ |
| | + $cb( (object)[ |
| | 'sha' => $curr, |
| | - 'message' => trim($msg), |
| | + 'message' => trim( $msg ), |
| | 'author' => $m[1] ?? 'Unknown', |
| | 'email' => $m[2] ?? '', |
| | - 'date' => (int)($m[3] ?? 0) |
| | - ]); |
| | + 'date' => (int)( $m[3] ?? 0 ) |
| | + ] ); |
| | |
| | - $curr = preg_match('/^parent ([0-9a-f]{40})$/m', $data, $ms) ? $ms[1] : ''; |
| | + $curr = preg_match( '/^parent ([0-9a-f]{40})$/m', $data, $ms ) ? $ms[1] : ''; |
| | $count++; |
| | } |
| | } |
| | |
| | - public function walk(string $refOrSha, callable $callback): void { |
| | - $sha = $this->resolve($refOrSha); |
| | - $data = ($sha !== '') ? $this->read($sha) : ''; |
| | + public function walk( string $refOrSha, callable $callback ): void { |
| | + $sha = $this->resolve( $refOrSha ); |
| | + $data = ($sha !== '') ? $this->read( $sha ) : ''; |
| | |
| | - if (preg_match('/^tree ([0-9a-f]{40})$/m', $data, $m)) { |
| | - $data = $this->read($m[1]); |
| | + if( preg_match( '/^tree ([0-9a-f]{40})$/m', $data, $m ) ) { |
| | + $data = $this->read( $m[1] ); |
| | } |
| | |
| | - if ($this->isTreeData($data)) { |
| | - $this->processTree($data, $callback); |
| | + if( $this->isTreeData( $data ) ) { |
| | + $this->processTree( $data, $callback ); |
| | } |
| | } |
| | |
| | - private function processTree(string $data, callable $callback): void { |
| | + private function processTree( string $data, callable $callback ): void { |
| | $pos = 0; |
| | - $len = strlen($data); |
| | + $len = strlen( $data ); |
| | |
| | - while ($pos < $len) { |
| | - $space = strpos($data, ' ', $pos); |
| | - $null = strpos($data, "\0", $space); |
| | - if ($space === false || $null === false) break; |
| | + while( $pos < $len ) { |
| | + $space = strpos( $data, ' ', $pos ); |
| | + $null = strpos( $data, "\0", $space ); |
| | + if( $space === false || $null === false ) break; |
| | |
| | - $mode = substr($data, $pos, $space - $pos); |
| | - $name = substr($data, $space + 1, $null - $space - 1); |
| | - $sha = bin2hex(substr($data, $null + 1, 20)); |
| | + $mode = substr( $data, $pos, $space - $pos ); |
| | + $name = substr( $data, $space + 1, $null - $space - 1 ); |
| | + $sha = bin2hex( substr( $data, $null + 1, 20 ) ); |
| | |
| | $isDir = ($mode === '40000' || $mode === '040000'); |
| | - $size = $isDir ? 0 : $this->getObjectSize($sha); |
| | + $size = $isDir ? 0 : $this->getObjectSize( $sha ); |
| | |
| | - $callback(new File($name, $sha, $mode, 0, $size)); |
| | + $callback( new File( $name, $sha, $mode, 0, $size ) ); |
| | $pos = $null + 21; |
| | } |
| | } |
| | |
| | - private function isTreeData(string $data): bool { |
| | + private function isTreeData( string $data ): bool { |
| | $pat = '/^(40000|100644|100755|120000|160000) /'; |
| | - if (strlen($data) >= 25 && preg_match($pat, $data)) { |
| | - $null = strpos($data, "\0"); |
| | - return ($null !== false && ($null + 21 <= strlen($data))); |
| | + if( strlen( $data ) >= 25 && preg_match( $pat, $data ) ) { |
| | + $null = strpos( $data, "\0" ); |
| | + return ($null !== false && ($null + 21 <= strlen( $data ))); |
| | } |
| | return false; |
| | } |
| | |
| | - private function getLoosePath(string $sha): string { |
| | - return "{$this->objPath}/" . substr($sha, 0, 2) . "/" . substr($sha, 2); |
| | + private function getLoosePath( string $sha ): string { |
| | + return "{$this->objPath}/" . substr( $sha, 0, 2 ) . "/" . substr( $sha, 2 ); |
| | } |
| | |
| | - private function getLooseObjectSize(string $sha): int { |
| | - $path = $this->getLoosePath($sha); |
| | - if (!file_exists($path)) return 0; |
| | + private function getLooseObjectSize( string $sha ): int { |
| | + $path = $this->getLoosePath( $sha ); |
| | + if( !file_exists( $path ) ) return 0; |
| | |
| | - $h = @fopen($path, 'rb'); |
| | - if (!$h) return 0; |
| | + $h = @fopen( $path, 'rb' ); |
| | + if( !$h ) return 0; |
| | |
| | $data = ''; |
| | - $inf = inflate_init(ZLIB_ENCODING_DEFLATE); |
| | + $inf = inflate_init( ZLIB_ENCODING_DEFLATE ); |
| | |
| | - while (!feof($h)) { |
| | - $chunk = fread($h, self::CHUNK_SIZE); |
| | - $out = @inflate_add($inf, $chunk, ZLIB_NO_FLUSH); |
| | - if ($out === false) break; |
| | + while( !feof( $h ) ) { |
| | + $chunk = fread( $h, self::CHUNK_SIZE ); |
| | + $out = @inflate_add( $inf, $chunk, ZLIB_NO_FLUSH ); |
| | + |
| | + if( $out === false ) break; |
| | $data .= $out; |
| | - if (strpos($data, "\0") !== false) break; |
| | + |
| | + if( strpos( $data, "\0" ) !== false ) break; |
| | } |
| | - fclose($h); |
| | + fclose( $h ); |
| | |
| | - $header = explode("\0", $data, 2)[0]; |
| | - $parts = explode(' ', $header); |
| | - return isset($parts[1]) ? (int)$parts[1] : 0; |
| | + $header = explode( "\0", $data, 2 )[0]; |
| | + $parts = explode( ' ', $header ); |
| | + |
| | + return isset( $parts[1] ) ? (int)$parts[1] : 0; |
| | } |
| | } |