borg-diff(1)
π borg-diff β ok so like, diffing two archives?? bestie we EAT π
hi bestie!! welcome to borg-diff. it's the borg subcommand that finds the differences between two archives β file contents, user, group, mode, all of it. it lives in the borg backup tool manual (borg-diff(1)), and honestly? iconic. let's go π¦
β¨ SYNOPSIS β¨
borg [common options] diff [options] REPO::ARCHIVE1 ARCHIVE2 [PATH...]
πΈ DESCRIPTION πΈ
This command finds differences (file contents, user/group/mode) between archives.
A repository location and an archive name must be specified for REPO::ARCHIVE1. ARCHIVE2 is just another archive name in the same repository (no repository location allowed). so likeβ¦ ARCHIVE2 is a guest in ARCHIVE1's house, no address of its own, periodt π
π What is compared π
For each matching item in both archives, Borg reports:
- Content changes: total added/removed bytes within files. If chunker parameters are comparable, Borg compares chunk IDs quickly; otherwise, it compares the content. (fast path vs. slow path, we love a range π)
- Metadata changes: user, group, mode, and other metadata shown inline like
"[old_mode -> new_mode]"for mode changes. Use--content-onlyto suppress metadata changes. - Added/removed items: printed as
"added SIZE path"or"removed SIZE path".
π Output formats π
The default (text) output shows one line per changed path, e.g.:
+135 B -252 B [ -rw-r--r-- -> -rwxr-xr-x ] path/to/file
JSON Lines output (--json-lines) prints one JSON object per changed path, e.g.:
{"path": "PATH", "changes": [
{"type": "modified", "added": BYTES, "removed": BYTES},
{"type": "mode", "old_mode": "-rw-r--r--", "new_mode": "-rwxr-xr-x"},
{"type": "added", "size": SIZE},
{"type": "removed", "size": SIZE}
]}
Only actual changes are included in the "changes" list. For example, a modified entry with added=0 and removed=0 is omitted. like, if nothing actually changed, it's not gonna be in the group chat, ok? no clout for zero-change entries π
π Sorting π
Use --sort-by FIELDS where FIELDS is a comma-separated list of fields. Sorts are applied stably from last to first in the given list. Prepend ">" for descending, "<" (or no prefix) for ascending, for example --sort-by=">size_added,path". Supported fields include:
path: the item pathsize_added: total bytes added for the item contentsize_removed: total bytes removed for the item contentsize_diff:size_added-size_removed(net content change)size: size of the item as stored in ARCHIVE2 (0 for removed items)user,group,uid,gid,ctime,mtime: taken from the item state in ARCHIVE2 when presentctime_diff,mtime_diff: timestamp difference (archive2 - archive1)
The --sort option is deprecated and only sorts by path. it's giving legacy, we don't use her anymore π
π Performance considerations π
For archives created with Borg 1.1 or newer, diff automatically detects whether the archives were created with the same chunker parameters. If so, only chunk IDs are compared, which is very fast. literally zoomies fast β‘
For archives prior to Borg 1.1, chunk contents are compared by default. If you did not create the archives with different chunker parameters, pass --same-chunker-params. Note that the chunker parameters changed from Borg 0.xx to 1.0.
For more help on include/exclude patterns, see the borg_patterns command output.
π«Ά OPTIONS π«Ά
See borg-common(1) for common options of Borg commands. (all the shared universal stuff lives over there, iykyk)
π§Ί arguments
REPO::ARCHIVE1β repository location and ARCHIVE1 nameARCHIVE2β ARCHIVE2 name (no repository location allowed)PATHβ paths of items inside the archives to compare; patterns are supported
β options
--numeric-ownerβ deprecated, use--numeric-idsinstead--numeric-idsβ only consider numeric user and group identifiers--same-chunker-paramsβ Override check of chunker parameters.--sortβ Sort the output by path (deprecated, use--sort-by=path).--sort-by FIELDSβ Advanced sorting: specify field(s) to sort by. Accepts a comma-separated list. Prefix with>for descending or<for ascending (default).--content-onlyβ Only compare differences in content (exclude metadata differences)--json-linesβ Format output as JSON Lines.
π Include/Exclude options π
-e PATTERN,--exclude PATTERNβ exclude paths matching PATTERN--exclude-from EXCLUDEFILEβ read exclude patterns from EXCLUDEFILE, one per line--pattern PATTERNβ include/exclude paths matching PATTERN--patterns-from PATTERNFILEβ read include/exclude patterns from PATTERNFILE, one per line
π₯ EXAMPLES π₯
ok bestie, demo time. watch and learn β¨
$ borg init -e=none testrepo
$ mkdir testdir
$ cd testdir
$ echo asdf > file1
$ dd if=/dev/urandom bs=1M count=4 > file2
$ touch file3
$ borg create ../testrepo::archive1 .
$ chmod a+x file1
$ echo "something" >> file2
$ borg create ../testrepo::archive2 .
$ echo "testing 123" >> file1
$ rm file3
$ touch file4
$ borg create ../testrepo::archive3 .
$ cd ..
$ borg diff testrepo::archive1 archive2
[-rw-r--r-- -> -rwxr-xr-x] file1
+135 B -252 B file2
$ borg diff testrepo::archive2 archive3
+17 B -5 B file1
added 0 B file4
removed 0 B file3
$ borg diff testrepo::archive1 archive3
+17 B -5 B [-rw-r--r-- -> -rwxr-xr-x] file1
+135 B -252 B file2
added 0 B file4
removed 0 B file3
$ borg diff --json-lines testrepo::archive1 archive3
{"path": "file1", "changes": [{"type": "modified", "added": 17, "removed": 5}, {"type": "mode", "old_mode": "-rw-r--r--", "new_mode": "-rwxr-xr-x"}]}
{"path": "file2", "changes": [{"type": "modified", "added": 135, "removed": 252}]}
{"path": "file4", "changes": [{"type": "added", "size": 0}]}
{"path": "file3", "changes": [{"type": "removed", "size": 0}]}
# Use --sort-by with a comma-separated list; sorts apply stably from last to first.
# Here: primary by net size change descending, tie-breaker by path ascending
$ borg diff --sort-by=">size_diff,path" testrepo::archive1 archive3
+17 B -5 B [-rw-r--r-- -> -rwxr-xr-x] file1
removed 0 B file3
added 0 B file4
+135 B -252 B file2
π SEE ALSO π
π Author π
The Borg Collective
no cap, that's the whole page. go diff something and slay π§
mwah π that was borg-diff(1) from the borg backup tool β this version's date stamp is 2026-07-18 and it's served fresh from the borg-diff(1) manual page, footer and all. take care of her, she's iconic πβ¨
π¦ where this page comes from
- alpine 3.24: borgbackup-doc 1.4.5-r0 Β· BSD-3-Clause
- arch rolling: borg 1.4.5-1 Β· BSD
- ubuntu stonking: borgbackup 1.4.5-1 Β· BSD-3-Clause
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms