code: def _on_tree(repo, tree, components, obj):
      
  
      # pattern-matching:
      if len(components) == 1:
          if isinstance(obj, Blob):
              mode = 0o100644
          elif isinstance(obj, Tree):
              mode = 0o040000
          elif obj is None:
              mode = None
          else:
              raise TypeError('Can only mount Blobs or Trees')
          name = components[0]
  
          if mode is not None:
              tree[name] = mode, obj.id
              return [tree]
          if name in tree:
              del tree[name]
          return [tree]
      elif len(components) > 1:
          a, bc = components[0], components[1:]
          if a in tree:
              a_tree = repo[tree[a][1]]
              if not isinstance(a_tree, Tree):
                  a_tree = Tree()
          else:
              a_tree = Tree()
          res = _on_tree(repo, a_tree, bc, obj)
          a_tree_new = res[-1]
  
          if a_tree_new.items():
              tree[a] = 0o040000, a_tree_new.id
              return res + [tree]
  
          # tree is empty
          if a in tree:
              del tree[a]
          return [tree]
      else:
          raise ValueError('Components can\'t be empty.')
docs: Mounts an object on a tree, using the given path components.
  
      :param tree: Tree object to mount on.
      :param components: A list of strings of subpaths (i.e. ['foo', 'bar'] is
                         equivalent to '/foo/bar')
      :param obj: Object to mount. If None, removes the object found at path
                  and prunes the tree downwards.
      :return: A list of new entities that need to be added to the object store,
               where the last one is the new tree.