code: func processObject(
  	s storer.EncodedObjectStorer,
  	h plumbing.Hash,
  	seen map[plumbing.Hash]bool,
  	visited map[plumbing.Hash]bool,
  	ignore []plumbing.Hash,
  	walkerFunc func(h plumbing.Hash),
  ) error {
  	if seen[h] {
  		return nil
  	}
  
  	o, err := s.EncodedObject(plumbing.AnyObject, h)
  	if err != nil {
  		return err
  	}
  
  	do, err := object.DecodeObject(s, o)
  	if err != nil {
  		return err
  	}
  
  	switch do := do.(type) {
  	case *object.Commit:
  		return reachableObjects(do, seen, visited, ignore, walkerFunc)
  	case *object.Tree:
  		return iterateCommitTrees(seen, do, walkerFunc)
  	case *object.Tag:
  		walkerFunc(do.Hash)
  		return processObject(s, do.Target, seen, visited, ignore, walkerFunc)
  	case *object.Blob:
  		walkerFunc(do.Hash)
  	default:
  		return fmt.Errorf("object type not valid: %s. "+
  			"Object reference: %s", o.Type(), o.Hash())
  	}
  
  	return nil
  }
docs: // processObject obtains the object using the hash an process it depending of its type