Esempio n. 1
0
def restore_backup(flags, bak_dir, num=None, name=None):
    """
    Tries to restore repository to a saved backup.
    Will prompt the user for the requested restore point if
    num is not set.
    - bak_dir   -- The backup storage directory.
    - num       -- The index number of the restore point (latest first).
    """
    try:
        check_git_rep()

        # If name is set just restore that file.
        if name is not None:
            bak_name = name

        else:
            # Find all previously backed up states.
            bak_files = get_files_with_extension(bak_dir, _BAK_FILE_EXT)
            if not bak_files:
                raise OpError("No backups exists in directory \'" +
                              bak_dir + "\'")

            # Sort the bak_files according to date.
            bak_files.sort(key=lambda bak_f: [int(v) for v in
                                              bak_f.split('_')[1].split('.')[
                                                  0].split('-')],
                           reverse=True)

            # Set the max tab depth.
            max_tab_depth = max([1 + (len(s.split('_')[0]) // _TAB_WIDTH)
                                 for s in bak_files])

            # Prompt user to select a state to restore.
            options = []
            for f_name in bak_files:
                option = "\t" + f_name.split('_')[0]
                option += "\t" * (max_tab_depth -
                                  len(f_name.split('_')[0]) // _TAB_WIDTH)
                option += datetime.strptime(
                    f_name.split('_')[1].split('.')[0],
                    _BAK_FILE_DATE_FORMAT).strftime(_BAK_DISPLAY_DATE_FORMAT)
                options.append(option)

            # Check if prompt can be skipped.
            if num is not None:
                if num >= len(options) or num < 0:
                    raise OpError("Invalid backup index \'" +
                                  num + "\' is outside [0-" +
                                  str(len(options) - 1) + "]")
            else:
                # Prompt.
                num = prompt_user_options("Select the backup to restore",
                                          options)
                if num is None:
                    raise OpError(msg="Restore aborted by user")

            # Set the chosen backup name.
            bak_name = bak_files[num]

        # Restore backup.
        try:
            log(flags, "Restoring backup \'" + bak_name + "\'")
            clean_dir(flags, getcwd())
            if not flags[Flag.SAFEMODE]:
                exec_cmd(["tar", "-xf", path.join(bak_dir, bak_name)])
        except Error as err:
            log(flags, "Restore failed, the backup can be found in \'" +
                bak_dir + "\'", TextType.ERR)
            raise OpError(err)
    except GitError as err:
        log(flags, "Restore could not be completed")
        raise OpError(err)