code: public static List<AsyncOneResponse> scheduleRepairs(ColumnFamily resolved, String keyspaceName, DecoratedKey key, List<ColumnFamily> versions, List<InetAddress> endpoints)
      {
          List<AsyncOneResponse> results = new ArrayList<AsyncOneResponse>(versions.size());
  
          for (int i = 0; i < versions.size(); i++)
          {
              ColumnFamily diffCf = ColumnFamily.diff(versions.get(i), resolved);
              if (diffCf == null) // no repair needs to happen
                  continue;
  
              // create and send the mutation message based on the diff
              Mutation mutation = new Mutation(keyspaceName, key.getKey(), diffCf);
              // use a separate verb here because we don't want these to be get the white glove hint-
              // on-timeout behavior that a "real" mutation gets
              results.add(MessagingService.instance().sendRR(mutation.createMessage(MessagingService.Verb.READ_REPAIR),
                                                             endpoints.get(i)));
          }
  
          return results;
      }
docs: For each row version, compare with resolved (the superset of all row versions);
  if it is missing anything, send a mutation to the endpoint it come from.