code: func (o Output) DiscardChangesToUntracked(ctx context.Context, tracked []string, dir string) error {
  	isTracked := TrackedSet(tracked)
  
  	for _, path := range o.Files() {
  		yes, err := isTracked(path)
  		if err != nil {
  			return err
  		}
  		if yes {
  			continue
  		}
  
  		logging.Warningf(ctx, "Discarding changes to %s, not in the tracked set", path)
  
  		if dir == "-" {
  			// When using stdout as destination, there's nowhere to read existing
  			// files from.
  			delete(o.Data, path)
  			continue
  		}
  
  		switch body, err := ioutil.ReadFile(filepath.Join(dir, filepath.FromSlash(path))); {
  		case err == nil:
  			o.Data[path] = body
  		case os.IsNotExist(err):
  			delete(o.Data, path)
  		case err != nil:
  			return errors.Annotate(err, "when discarding changes to %s", path).Err()
  		}
  	}
  
  	return nil
  }
docs: // DiscardChangesToUntracked replaces bodies of the files that are in the output
  // set, but not in the `tracked` set (per TrackedSet semantics) with what's on
  // disk in the given `dir`.
  //
  // This allows to construct partially generated output: some configs (the ones
  // in the tracked set) are generated, others are loaded from disk.
  //
  // If `dir` is "-" (which indicates that the output is going to be dumped to
  // stdout rather then to disk), just removes untracked files from the output.