public function fetchRawObject($sha)
{
// Unpacked case
if ($this->isLoose($sha)) {
$first = substr($sha, 0, 2);
$last = substr($sha, 2);
$loose_object_path = 'objects/' . $first . '/' . $last;
$compressed_data = $this->readFileRelative($loose_object_path);
$uncompressed_data = @gzuncompress($compressed_data);
if ($uncompressed_data === false) {
throw new InvalidObjectException(sprintf('Couldn\'t decompress Git object in %s.', $this->resolveRelativePath($loose_object_path)));
}
if (strlen($uncompressed_data) == 0) {
throw new InvalidObjectException("Attempting to hydrate empty object");
}
sscanf($uncompressed_data, "%s %d", $type, $length);
$offset = strlen($type) + strlen($length) + 2;
//Space and NUL
$raw_object = new RawObject($type, substr($uncompressed_data, $offset));
if ($raw_object->getLength() !== $length) {
throw new InvalidObjectException(sprintf("Length derived from git object header (%d) does not match actual length (%d)", $offset + $length, strlen($uncompressed_data)));
}
if ($raw_object->getSha() != $sha) {
throw new InvalidObjectException(sprintf("Unexpected RawObject sha, expected %s, was %s", $sha, $raw_object->getSha()));
}
return $raw_object;
} else {
// Maybe it's packed?
foreach ($this->getPackfiles() as $packfile) {
if ($packfile->hasSha($sha)) {
return $packfile->getRawObjectForSha($sha);
}
}
}
return null;
}