/** * @brief Updates a node in this tree. * Missing directories in the path will be created automatically. * @param string $path Path to the node, relative to this tree. * @param Glip_Git $mode mode to set the node to. 0 if the node shall be * cleared, i.e. the tree or blob shall be removed from this path. * @param string $object Glip_Binary SHA-1 hash of the object that shall be * placed at the given path. * @throws Glip_GitTreeInvalidPathError * @returns Glip_GitObject[] An array of Glip_GitObject%s that were newly * created while updating the specified node. Those need to be written to * the repository together with the modified tree. */ public function updateNode($path, $mode, $object) { if (!is_array($path)) { $path = explode('/', $path); } $name = array_shift($path); if (count($path) == 0) { /* create leaf node */ if ($mode) { $node = new \stdClass(); $node->mode = $mode; $node->name = $name; $node->object = $object; $node->is_dir = !!($mode & 040000); $this->nodes[$node->name] = $node; } else { unset($this->nodes[$name]); } return array(); } else { /* descend one level */ if (isset($this->nodes[$name])) { $node = $this->nodes[$name]; if (!$node->is_dir) { throw new Glip_GitTreeInvalidPathError(); } $subtree = clone $this->repo->getObject($node->object); } else { /* create new tree */ $subtree = new Glip_GitTree($this->repo); $node = new \stdClass(); $node->mode = 040000; $node->name = $name; $node->is_dir = true; $this->nodes[$node->name] = $node; } $pending = $subtree->updateNode($path, $mode, $object); $subtree->rehash(); $node->object = $subtree->getName(); $pending[] = $subtree; return $pending; } }