def join(self, file: str) -> IndexObjUnion:
        """Find the named object in this tree's contents.

        :return:
            :class:`~git.objects.blob.Blob`, :class:`Tree`, or
            :class:`~git.objects.submodule.base.Submodule`

        :raise KeyError:
            If the given file or tree does not exist in this tree.
        """
        msg = "Blob or Tree named %r not found"
        if "/" in file:
            tree = self
            item = self
            tokens = file.split("/")
            for i, token in enumerate(tokens):
                item = tree[token]
                if item.type == "tree":
                    tree = item
                else:
                    # Safety assertion - blobs are at the end of the path.
                    if i != len(tokens) - 1:
                        raise KeyError(msg % file)
                    return item
                # END handle item type
            # END for each token of split path
            if item == self:
                raise KeyError(msg % file)
            return item
        else:
            for info in self._cache:
                if info[2] == file:  # [2] == name
                    return self._map_id_to_type[info[1] >> 12](
                        self.repo, info[0], info[1], join_path(self.path, info[2])
                    )
            # END for each obj
            raise KeyError(msg % file)
        # END handle long paths
Find the named object in this tree's contents.

        :return:
            :class:`~git.objects.blob.Blob`, :class:`Tree`, or
            :class:`~git.objects.submodule.base.Submodule`

        :raise KeyError:
            If the given file or tree does not exist in this tree.
        
git/objects/tree.py