Skip to content

diff: add --stats, showing a summary of the differences - #10327

Open
ThomasWaldmann wants to merge 2 commits into
borgbackup:masterfrom
ThomasWaldmann:diff-stats-796
Open

diff: add --stats, showing a summary of the differences#10327
ThomasWaldmann wants to merge 2 commits into
borgbackup:masterfrom
ThomasWaldmann:diff-stats-796

Conversation

@ThomasWaldmann

Copy link
Copy Markdown
Member

Fixes #796.

borg diff so far only reported per-item changes. This adds -s / --stats,
printing an aggregated summary after the per-path output:

Added items: 23
Removed items: 2
Changed items: 315
Added chunk volume: 53.70 MB
Removed chunk volume: 51.10 MB
  • Added / removed items only exist in ARCHIVE2 / ARCHIVE1, changed items
    exist in both archives but differ.
  • Added / removed chunk volume sum up the size of the content chunks
    added/removed by all of these items (a modified file contributes both its new
    and its old chunk bytes).
  • --content-only narrows the counts the same way it narrows the output.

If the archives were created with different chunker params, borg compares the
content byte by byte and cannot tell by how much it changed. Such items
contribute no byte counts, so the totals are not silently misleading — an
additional line reports how many there are:

Items with unknown size changes: 1

The text summary goes to the borg.output.stats logger (stderr), like the
--stats output of other commands, so stdout stays clean for piping. With
--json-lines, the summary is emitted as a final line of its own shape
instead, so existing per-path parsers are unaffected:

{"stats": {"added_chunk_volume": 242000, "added_items": 2, "changed_items": 1, "removed_chunk_volume": 105000, "removed_items": 2, "unknown_size_items": 0}}

The change filtering that the text and JSON output paths each did separately is
now done once in reported_changes(), feeding both the output and the stats, so
the summary counts exactly what was printed.

Tests cover the text summary, metadata-only changes counting as changed items,
the JSON Lines summary, the unknown-size path, and that nothing is printed
without the flag. The diff epilog documents all of the above.

🤖 Generated with Claude Code

…ckup#796

borg diff so far only reported per-item changes. Add -s/--stats, printing
an aggregated summary after the per-path output:

    Added items: 23
    Removed items: 2
    Changed items: 315
    Added chunk volume: 53.70 MB
    Removed chunk volume: 51.10 MB

Added/removed items only exist in one of the archives, changed items exist
in both but differ. The chunk volumes sum up the size of the content chunks
added/removed by all of these items.

If the archives were created with different chunker params, borg compares
the content byte by byte and cannot tell by how much it changed. Such items
contribute no byte counts, so an additional "Items with unknown size changes"
line reports how many there are.

The text summary goes to the borg.output.stats logger (stderr), like the
--stats output of other commands, so stdout stays clean for piping. With
--json-lines, the summary is emitted as a final {"stats": {...}} line
instead, which is easy to tell apart from the per-path lines.

The change filtering that the text and JSON output paths did separately is
now done once in reported_changes(), feeding both the output and the stats,
so the summary counts exactly what was printed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@codecov

codecov Bot commented Sep 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.72%. Comparing base (e861c72) to head (f554346).
⚠️ Report is 11 commits behind head on master.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##           master   #10327      +/-   ##
==========================================
+ Coverage   87.65%   87.72%   +0.07%     
==========================================
  Files         103      103              
  Lines       18716    18756      +40     
  Branches     2881     2889       +8     
==========================================
+ Hits        16405    16454      +49     
+ Misses       1609     1600       -9     
  Partials      702      702              

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

test_stats_counts_metadata_only_changes made its metadata-only change with
os.chmod(0o700). On Windows, chmod only toggles the read-only bit, so the
stored mode did not change and file_touched was not reported as a changed
item at all: the test expected 3 changed items, but got 2.

Change the file's mtime instead, which is a metadata change borg reports on
every platform.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Show general statistics with 'borg diff'

1 participant