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)