code: def join(self, file):
          
          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)
docs: Find the named object in this tree's contents
          :return: ``git.Blob`` or ``git.Tree`` or ``git.Submodule``
  
          :raise KeyError: if given file or tree does not exist in tree