code: func (f *sendOnlyFolder) pull() bool {
  	select {
  	case <-f.initialScanFinished:
  	default:
  		// Once the initial scan finished, a pull will be scheduled
  		return false
  	}
  
  	batch := make([]protocol.FileInfo, 0, maxBatchSizeFiles)
  	batchSizeBytes := 0
  
  	f.fset.WithNeed(protocol.LocalDeviceID, func(intf db.FileIntf) bool {
  		if len(batch) == maxBatchSizeFiles || batchSizeBytes > maxBatchSizeBytes {
  			f.updateLocalsFromPulling(batch)
  			batch = batch[:0]
  			batchSizeBytes = 0
  		}
  
  		if f.ignores.ShouldIgnore(intf.FileName()) {
  			file := intf.(protocol.FileInfo)
  			file.SetIgnored(f.shortID)
  			batch = append(batch, file)
  			batchSizeBytes += file.ProtoSize()
  			l.Debugln(f, "Handling ignored file", file)
  			return true
  		}
  
  		curFile, ok := f.fset.Get(protocol.LocalDeviceID, intf.FileName())
  		if !ok {
  			if intf.IsDeleted() {
  				panic("Should never get a deleted file as needed when we don't have it")
  			}
  			return true
  		}
  
  		file := intf.(protocol.FileInfo)
  		if !file.IsEquivalentOptional(curFile, f.IgnorePerms, false, 0) {
  			return true
  		}
  
  		file.Version = file.Version.Merge(curFile.Version)
  		batch = append(batch, file)
  		batchSizeBytes += file.ProtoSize()
  		l.Debugln(f, "Merging versions of identical file", file)
  
  		return true
  	})
  
  	if len(batch) > 0 {
  		f.updateLocalsFromPulling(batch)
  	}
  
  	return true
  }
docs: // pull checks need for files that only differ by metadata (no changes on disk)