protected List<BackupImage> getAncestors(BackupInfo backupInfo) throws IOException {
    LOG.debug("Getting the direct ancestors of the current backup {}", backupInfo.getBackupId());

    // Full backups do not have ancestors
    if (backupInfo.getType() == BackupType.FULL) {
      LOG.debug("Current backup is a full backup, no direct ancestor for it.");
      return Collections.emptyList();
    }

    List<BackupImage> ancestors = new ArrayList<>();
    Set<TableName> tablesToCover = new HashSet<>(backupInfo.getTables());

    // Go over the backup history list from newest to oldest
    List<BackupInfo> allHistoryList = backupManager.getBackupHistory(true);
    for (BackupInfo backup : allHistoryList) {
      // If the image has a different rootDir, it cannot be an ancestor.
      if (!Objects.equals(backup.getBackupRootDir(), backupInfo.getBackupRootDir())) {
        continue;
      }

      BackupImage.Builder builder = BackupImage.newBuilder();
      BackupImage image = builder.withBackupId(backup.getBackupId()).withType(backup.getType())
        .withRootDir(backup.getBackupRootDir()).withTableList(backup.getTableNames())
        .withStartTime(backup.getStartTs()).withCompleteTime(backup.getCompleteTs()).build();

      // The ancestors consist of the most recent FULL backups that cover the list of tables
      // required in the new backup and all INCREMENTAL backups that came after one of those FULL
      // backups.
      if (backup.getType().equals(BackupType.INCREMENTAL)) {
        ancestors.add(image);
        LOG.debug("Dependent incremental backup image: {BackupID={}}", image.getBackupId());
      } else {
        if (tablesToCover.removeAll(new HashSet<>(image.getTableNames()))) {
          ancestors.add(image);
          LOG.debug("Dependent full backup image: {BackupID={}}", image.getBackupId());

          if (tablesToCover.isEmpty()) {
            LOG.debug("Got {} ancestors for the current backup.", ancestors.size());
            return Collections.unmodifiableList(ancestors);
          }
        }
      }
    }

    throw new IllegalStateException(
      "Unable to find full backup that contains tables: " + tablesToCover);
  }
Gets the direct ancestors of the currently being created backup.
@param backupInfo The backup info for the backup being created
hbase-backup/src/main/java/org/apache/hadoop/hbase/backup/impl/TableBackupClient.java