'Displays all saved checkpoints.
All checkpoints are printed by
:meth:`certbot.interfaces.IDisplay.notification`.
.. todo:: Decide on a policy for error handling, OSError IOError...
:raises .errors.ReverterError: If invalid directory structure.'

def view_config_changes(self, for_logging=False, num=None):

    backups = os.listdir(self.config.backup_dir)
    backups.sort(reverse=True)
    if num:
        backups = backups[:num]
    if (not backups):
        logger.info('Certbot    has    not    saved    backups    of    your    configuration')
        return
    try:
        for bkup in backups:
            float(bkup)
    except ValueError:
        raise errors.ReverterError('Invalid    directories    in    {0}'.format(self.config.backup_dir))
    output = []
    for bkup in backups:
        output.append(time.ctime(float(bkup)))
        cur_dir = os.path.join(self.config.backup_dir, bkup)
        with open(os.path.join(cur_dir, 'CHANGES_SINCE')) as changes_fd:
            output.append(changes_fd.read())
        output.append('Affected    files:')
        with open(os.path.join(cur_dir, 'FILEPATHS')) as paths_fd:
            filepaths = paths_fd.read().splitlines()
            for path in filepaths:
                output.append('        {0}'.format(path))
        if os.path.isfile(os.path.join(cur_dir, 'NEW_FILES')):
            with open(os.path.join(cur_dir, 'NEW_FILES')) as new_fd:
                output.append('New    Configuration    Files:')
                filepaths = new_fd.read().splitlines()
                for path in filepaths:
                    output.append('        {0}'.format(path))
        output.append(os.linesep)
    if for_logging:
        return os.linesep.join(output)
    zope.component.getUtility(interfaces.IDisplay).notification(os.linesep.join(output), force_interactive=True)
