/** * Get any object from the repository. * * @param string $name Reference name or (partial) object hash * @return Object Immutable Object of given name. * @throws \InvalidArgumentException * @throws \OutOfBoundsException */ public function get($name) { $hash = false; if (ctype_xdigit($name)) { $hash_len = strlen($name); if ($hash_len < 4) { throw new \InvalidArgumentException('Hash must be at least 4 characters long.'); } if ($hash_len % 2) { throw new \InvalidArgumentException('Hash must be divisible by two.'); } $hash = $name; } elseif (array_key_exists($name, $this->refs)) { $hash = $this->refs[$name]; } else { throw new \InvalidArgumentException('Invalid ref: ' . $name); } $data = false; $objectPath = $this->path . '/objects/' . substr($hash, 0, 2) . '/' . substr($hash, 2); if (strlen($hash) < 40) { $hits = glob($objectPath . '*'); if (count($hits) > 0) { $data = gzuncompress(file_get_contents($hits[0])); } } elseif (file_exists($objectPath)) { $data = gzuncompress(file_get_contents($objectPath)); } if (!$data) { foreach ($this->packs as &$pack) { $data = $pack->search($hash); if ($data) { break; } } } if (!$data) { throw new \OutOfBoundsException($name); } $hash = strlen($hash) == 40 ? $hash : sha1($data); list($prefix, $body) = explode("", $data, 2); list($type, $size) = explode(' ', $prefix, 2); switch ($type) { case 'commit': return Commit::fromRaw($body, $size, $hash); case 'tag': return Tag::fromRaw($body, $size, $hash); case 'tree': return Tree::fromRaw($body, $size, $hash); case 'blob': return Blob::fromRaw($body, $size, $hash); default: throw new InvalidArgumentException($type); } }