code: func (s *scheduler) mergeTo(target, src *edge) bool {
  	if !target.edge.Vertex.Options().IgnoreCache && src.edge.Vertex.Options().IgnoreCache {
  		return false
  	}
  	for _, inc := range s.incoming[src] {
  		inc.mu.Lock()
  		inc.Target = target
  		s.incoming[target] = append(s.incoming[target], inc)
  		inc.mu.Unlock()
  	}
  
  	for _, out := range s.outgoing[src] {
  		out.mu.Lock()
  		out.From = target
  		s.outgoing[target] = append(s.outgoing[target], out)
  		out.mu.Unlock()
  		out.Receiver.Cancel()
  	}
  
  	delete(s.incoming, src)
  	delete(s.outgoing, src)
  	s.signal(target)
  
  	for i, d := range src.deps {
  		for _, k := range d.keys {
  			target.secondaryExporters = append(target.secondaryExporters, expDep{i, CacheKeyWithSelector{CacheKey: k, Selector: src.cacheMap.Deps[i].Selector}})
  		}
  		if d.slowCacheKey != nil {
  			target.secondaryExporters = append(target.secondaryExporters, expDep{i, CacheKeyWithSelector{CacheKey: *d.slowCacheKey}})
  		}
  		if d.result != nil {
  			for _, dk := range d.result.CacheKeys() {
  				target.secondaryExporters = append(target.secondaryExporters, expDep{i, CacheKeyWithSelector{CacheKey: dk, Selector: src.cacheMap.Deps[i].Selector}})
  			}
  		}
  	}
  
  	// TODO(tonistiigi): merge cache providers
  
  	return true
  }
docs: // mergeTo merges the state from one edge to another. source edge is discarded.