code: def revs(self, branch='master', limit=None, skip=None, num_datapoints=None):
          
  
          if limit is not None:
              limit = math.floor(float(limit) / len(self.repos))
  
          if num_datapoints is not None:
              num_datapoints = math.floor(float(num_datapoints) / len(self.repos))
  
          df = pd.DataFrame(columns=['repository', 'rev'])
  
          if _has_joblib:
              ds = Parallel(n_jobs=-1, backend='threading', verbose=0)(
                  delayed(_revs_func)
                  (x, branch, limit, skip, num_datapoints) for x in self.repos
              )
              for d in ds:
                  df = df.append(d)
          else:
              for repo in self.repos:
                  try:
                      revs = repo.revs(branch=branch, limit=limit, skip=skip, num_datapoints=num_datapoints)
                      revs['repository'] = repo.repo_name
                      df = df.append(revs)
                  except GitCommandError:
                      print('Warning! Repo: %s couldn\'t be inspected' % (repo, ))
  
          df.reset_index()
  
          return df
docs: Returns a dataframe of all revision tags and their timestamps for each project. It will have the columns:
  
           * date
           * repository
           * rev
  
          :param branch: (optional, default 'master') the branch to work in
          :param limit: (optional, default None), the maximum number of revisions to return, None for no limit
          :param skip: (optional, default None), the number of revisions to skip. Ex: skip=2 returns every other revision, None for no skipping.
          :param num_datapoints: (optional, default=None) if limit and skip are none, and this isn't, then num_datapoints evenly spaced revs will be used
  
          :return: DataFrame