Skip to content

Commit

Permalink
Add flags to borg extract Command (Fixes borgbackup#8564) (borgbackup…
Browse files Browse the repository at this point in the history
…#8575)

borg extract --dry-run now displays +/- flags (included/excluded) left to the path.
  • Loading branch information
alighazi288 authored Dec 27, 2024
1 parent 26b2ffc commit ec3c7b5
Show file tree
Hide file tree
Showing 2 changed files with 59 additions and 23 deletions.
63 changes: 40 additions & 23 deletions src/borg/archiver/extract_cmd.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,33 +56,50 @@ def do_extract(self, args, repository, manifest, archive):
else:
pi = None

for item in archive.iter_items(filter):
archive.preload_item_chunks(item, optimize_hardlinks=True)
for item in archive.iter_items():
orig_path = item.path
if strip_components:
item.path = os.sep.join(orig_path.split(os.sep)[strip_components:])
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))
stripped_path = os.sep.join(orig_path.split(os.sep)[strip_components:])
if not stripped_path:
continue
item.path = stripped_path

is_matched = matcher.match(orig_path)

if output_list:
logging.getLogger("borg.output.list").info(remove_surrogates(item.path))
try:
if dry_run:
archive.extract_item(item, dry_run=True, hlm=hlm, pi=pi)
else:
if stat.S_ISDIR(item.mode):
dirs.append(item)
archive.extract_item(item, stdout=stdout, restore_attrs=False)
log_prefix = "+" if is_matched else "-"
logging.getLogger("borg.output.list").info(f"{log_prefix} {remove_surrogates(item.path)}")

if is_matched:
archive.preload_item_chunks(item, optimize_hardlinks=True)

if not 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:
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 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()

Expand Down
19 changes: 19 additions & 0 deletions src/borg/testsuite/archiver/extract_cmd_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -718,3 +718,22 @@ def test_extract_continue(archivers, request):
assert f.read() == CONTENTS2
with open("input/file3", "rb") as f:
assert f.read() == CONTENTS3


def test_dry_run_extraction_flags(archivers, request):
archiver = request.getfixturevalue(archivers)
cmd(archiver, "repo-create", RK_ENCRYPTION)
create_regular_file(archiver.input_path, "file1", 0)
create_regular_file(archiver.input_path, "file2", 0)
create_regular_file(archiver.input_path, "file3", 0)
cmd(archiver, "create", "test", "input")

output = cmd(archiver, "extract", "--dry-run", "--list", "test", "-e", "input/file3")

expected_output = ["+ input/file1", "+ input/file2", "- input/file3"]
output_lines = output.splitlines()
for expected in expected_output:
assert expected in output_lines, f"Expected line not found: {expected}"
print(output)

assert not os.listdir("output"), "Output directory should be empty after dry-run"

0 comments on commit ec3c7b5

Please sign in to comment.