diff --git a/src/borg/archiver/extract_cmd.py b/src/borg/archiver/extract_cmd.py index aa3b6c4df5..19222dc61a 100644 --- a/src/borg/archiver/extract_cmd.py +++ b/src/borg/archiver/extract_cmd.py @@ -56,53 +56,55 @@ def do_extract(self, args, repository, manifest, archive): else: pi = None - excluded_items = [] - # First pass to identify excluded items for item in archive.iter_items(preload=True): - if not matcher.match(item.path): - excluded_items.append(item.path) - - for item in archive.iter_items(filter, preload=True): orig_path = item.path - if strip_components: - item.path = os.sep.join(orig_path.split(os.sep)[strip_components:]) + components = orig_path.split(os.sep) + if strip_components >= len(components): + sanitized_path = "" + else: + sanitized_path = os.sep.join(components[strip_components:]) + + if not sanitized_path: + continue - if not args.dry_run: - while dirs and not item.path.startswith(dirs[-1].path): - dir_item = dirs.pop(-1) - try: - archive.extract_item(dir_item, stdout=stdout) - except BackupError as e: - self.print_warning_instance(BackupWarning(remove_surrogates(dir_item.path), e)) + item.path = sanitized_path is_matched = matcher.match(item.path) - try: - log_prefix = "+" if is_matched else "-" - logging.getLogger("borg.output.list").info(f"{log_prefix} {remove_surrogates(item.path)}") - if dry_run: - archive.extract_item(item, dry_run=True, hlm=hlm, pi=pi) - else: - if is_matched: - if stat.S_ISDIR(item.mode): - dirs.append(item) - archive.extract_item(item, stdout=stdout, restore_attrs=False) - else: - archive.extract_item( - item, - stdout=stdout, - sparse=sparse, - hlm=hlm, - pi=pi, - continue_extraction=continue_extraction, - ) - except BackupError as e: - self.print_warning_instance(BackupWarning(remove_surrogates(orig_path), e)) + log_prefix = "+" if is_matched else "-" + logging.getLogger("borg.output.list").info(f"{log_prefix} {remove_surrogates(item.path)}") + + if is_matched: + + if not args.dry_run: + while dirs and not item.path.startswith(dirs[-1].path): + dir_item = dirs.pop(-1) + try: + archive.extract_item(dir_item, stdout=stdout) + except BackupError as e: + self.print_warning_instance(BackupWarning(remove_surrogates(dir_item.path), e)) + + try: + if dry_run: + archive.extract_item(item, dry_run=True, hlm=hlm, pi=pi) + else: + if is_matched: + if stat.S_ISDIR(item.mode): + dirs.append(item) + archive.extract_item(item, stdout=stdout, restore_attrs=False) + else: + archive.extract_item( + item, + stdout=stdout, + sparse=sparse, + hlm=hlm, + pi=pi, + continue_extraction=continue_extraction, + ) + except BackupError as e: + self.print_warning_instance(BackupWarning(remove_surrogates(orig_path), e)) + if pi: pi.finish() - # Display excluded items - if excluded_items: - for excluded_item in excluded_items: - logging.getLogger("borg.output.list").info(f"- {remove_surrogates(excluded_item)}") if not args.dry_run: pi = ProgressIndicatorPercent(