Dave Jarvis' Repositories

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

Updates packed object sizes

AuthorDave Jarvis <email>
Date2026-02-09 00:44:59 GMT-0800
Commita48a453eb1f278abea3bf5d7186d548861912554
Parente96d4db
Git.php
}
- private function getPackedObjectSize(string $sha): int {
+private function getPackedObjectSize(string $sha): int {
$info = $this->getPackOffset($sha);
if (!$info) return 0;
$size = $byte & 15;
$shift = 4;
+
while ($byte & 128) {
$byte = ord(fread($pf, 1));
$size |= (($byte & 127) << $shift);
$shift += 7;
}
- if ($type === 6 || $type === 7) {
- if ($type === 6) { // OFS_DELTA
- $byte = ord(fread($pf, 1));
- while ($byte & 128) { $byte = ord(fread($pf, 1)); }
- } else { // REF_DELTA
- fread($pf, 20);
- }
+ // If the object is not a delta, the size we just read is the final size.
+ if ($type !== 6 && $type !== 7) {
+ fclose($pf);
+ return $size;
+ }
- $ctx = inflate_init(ZLIB_ENCODING_DEFLATE);
- $buffer = '';
- $found = false;
- while (!$found && !feof($pf)) {
- $chunk = fread($pf, 512);
- $inflated = @inflate_add($ctx, $chunk, ZLIB_NO_FLUSH);
- if ($inflated === false) { fclose($pf); return 0; }
- $buffer .= $inflated;
- if (strlen($buffer) > 32) $found = true;
- }
+ // For Deltas (Type 6 or 7), the 'size' above is the size of the delta data,
+ // not the resulting file. We must find the "Target Size" inside the delta header.
+ if ($type === 6) { // OFS_DELTA: skip the negative offset
+ $byte = ord(fread($pf, 1));
+ while ($byte & 128) { $byte = ord(fread($pf, 1)); }
+ } else { // REF_DELTA: skip the 20-byte base SHA
+ fread($pf, 20);
+ }
- $pos = 0;
- // Skip Source Size
- if (!isset($buffer[$pos])) { fclose($pf); return 0; }
- $byte = ord($buffer[$pos++]);
- while ($byte & 128) {
- if (!isset($buffer[$pos])) break;
- $byte = ord($buffer[$pos++]);
- }
- // Read Target Size
- if (!isset($buffer[$pos])) { fclose($pf); return 0; }
- $byte = ord($buffer[$pos++]);
- $size = $byte & 127;
- $shift = 7;
- while ($byte & 128) {
- if (!isset($buffer[$pos])) break;
- $byte = ord($buffer[$pos++]);
- $size |= (($byte & 127) << $shift);
- $shift += 7;
- }
+ // Inflate only the beginning of the delta data to get the header
+ $ctx = inflate_init(ZLIB_ENCODING_DEFLATE);
+ $headerData = '';
+ while (!feof($pf)) {
+ $chunk = fread($pf, 512);
+ $inflated = @inflate_add($ctx, $chunk, ZLIB_NO_FLUSH);
+ if ($inflated !== false) $headerData .= $inflated;
+ if (strlen($headerData) >= 32) break; // We usually only need ~10 bytes
}
fclose($pf);
- return $size;
+
+ if (strlen($headerData) === 0) return 0;
+
+ $pos = 0;
+ // 1. Skip Source Size (Base Object Size)
+ $byte = ord($headerData[$pos++]);
+ while ($byte & 128 && $pos < strlen($headerData)) {
+ $byte = ord($headerData[$pos++]);
+ }
+
+ // 2. Read Target Size (The actual file size we want to display)
+ if ($pos >= strlen($headerData)) return 0;
+ $byte = ord($headerData[$pos++]);
+ $targetSize = $byte & 127;
+ $shift = 7;
+ while ($byte & 128 && $pos < strlen($headerData)) {
+ $byte = ord($headerData[$pos++]);
+ $targetSize |= (($byte & 127) << $shift);
+ $shift += 7;
+ }
+
+ return $targetSize;
}
Delta45 lines added, 38 lines removed, 7-line increase