.\" Man page generated from reStructuredText. . . .nr rst2man-indent-level 0 . .de1 rstReportMargin \\$1 \\n[an-margin] level \\n[rst2man-indent-level] level margin: \\n[rst2man-indent\\n[rst2man-indent-level]] - \\n[rst2man-indent0] \\n[rst2man-indent1] \\n[rst2man-indent2] .. .de1 INDENT .\" .rstReportMargin pre: . RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .\" .rstReportMargin post: .. .de UNINDENT . RE .\" indent \\n[an-margin] .\" old: \\n[rst2man-indent\\n[rst2man-indent-level]] .nr rst2man-indent-level -1 .\" new: \\n[rst2man-indent\\n[rst2man-indent-level]] .in \\n[rst2man-indent\\n[rst2man-indent-level]]u .. .TH "BORG-DIFF" "1" "2025-12-23" "" "borg backup tool" .SH NAME borg-diff \- Finds differences between two archives. .SH SYNOPSIS .sp borg [common options] diff [options] ARCHIVE1 ARCHIVE2 [PATH...] .SH DESCRIPTION .sp This command finds differences (file contents, metadata) between ARCHIVE1 and ARCHIVE2. .sp For more help on include/exclude patterns, see the output of the \fIborg_patterns\fP command. .SH OPTIONS .sp See \fIborg\-common(1)\fP for common options of Borg commands. .SS arguments .INDENT 0.0 .TP .B ARCHIVE1 ARCHIVE1 name .TP .B ARCHIVE2 ARCHIVE2 name .TP .B PATH paths of items inside the archives to compare; patterns are supported. .UNINDENT .SS options .INDENT 0.0 .TP .B \-\-numeric\-ids only consider numeric user and group identifiers .TP .B \-\-same\-chunker\-params override the check of chunker parameters .TP .BI \-\-format \ FORMAT specify format for differences between archives (default: \(dq{change} {path}{NL}\(dq) .TP .B \-\-json\-lines Format output as JSON Lines. .TP .B \-\-sort\-by Sort output by comma\-separated fields (e.g., \(aq>size_added,path\(aq). .TP .B \-\-content\-only Only compare differences in content (exclude metadata differences) .UNINDENT .SS Include/Exclude options .INDENT 0.0 .TP .BI \-e \ PATTERN\fR,\fB \ \-\-exclude \ PATTERN exclude paths matching PATTERN .TP .BI \-\-exclude\-from \ EXCLUDEFILE read exclude patterns from EXCLUDEFILE, one per line .TP .BI \-\-pattern \ PATTERN include/exclude paths matching PATTERN .TP .BI \-\-patterns\-from \ PATTERNFILE read include/exclude patterns from PATTERNFILE, one per line .UNINDENT .SH EXAMPLES .INDENT 0.0 .INDENT 3.5 .sp .EX $ borg diff archive1 archive2 +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 archive1 archive2 {\(dqpath\(dq: \(dqfile1\(dq, \(dqchanges\(dq: [{\(dqtype\(dq: \(dqmodified\(dq, \(dqadded\(dq: 17, \(dqremoved\(dq: 5}, {\(dqtype\(dq: \(dqmode\(dq, \(dqold_mode\(dq: \(dq\-rw\-r\-\-r\-\-\(dq, \(dqnew_mode\(dq: \(dq\-rwxr\-xr\-x\(dq}]} {\(dqpath\(dq: \(dqfile2\(dq, \(dqchanges\(dq: [{\(dqtype\(dq: \(dqmodified\(dq, \(dqadded\(dq: 135, \(dqremoved\(dq: 252}]} {\(dqpath\(dq: \(dqfile4\(dq, \(dqchanges\(dq: [{\(dqtype\(dq: \(dqadded\(dq, \(dqsize\(dq: 0}]} {\(dqpath\(dq: \(dqfile3\(dq, \(dqchanges\(dq: [{\(dqtype\(dq: \(dqremoved\(dq, \(dqsize\(dq: 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=\(dq>size_diff,path\(dq archive1 archive2 +17 B \-5 B [\-rw\-r\-\-r\-\- \-> \-rwxr\-xr\-x] file1 removed 0 B file3 added 0 B file4 +135 B \-252 B file2 .EE .UNINDENT .UNINDENT .SH NOTES .SS The FORMAT specifier syntax .sp The \fB\-\-format\fP option uses Python\(aqs format string syntax \&. .sp Examples: .INDENT 0.0 .INDENT 3.5 .sp .EX $ borg diff \-\-format \(aq{content:30} {path}{NL}\(aq ArchiveFoo ArchiveBar modified: +4.1 kB \-1.0 kB file\-diff \&... # {VAR:NUMBER} \- pad to NUMBER columns right\-aligned. $ borg diff \-\-format \(aq{content:>30} {path}{NL}\(aq ArchiveFoo ArchiveBar modified: +4.1 kB \-1.0 kB file\-diff \&... .EE .UNINDENT .UNINDENT .sp The following keys are always available: .INDENT 0.0 .IP \(bu 2 NEWLINE: OS dependent line separator .IP \(bu 2 NL: alias of NEWLINE .IP \(bu 2 NUL: NUL character for creating print0 / xargs \-0 like output .IP \(bu 2 SPACE: space character .IP \(bu 2 TAB: tab character .IP \(bu 2 CR: carriage return character .IP \(bu 2 LF: line feed character .UNINDENT .sp Keys available only when showing differences between archives: .INDENT 0.0 .IP \(bu 2 path: archived file path .IP \(bu 2 change: all available changes .IP \(bu 2 content: file content change .IP \(bu 2 mode: file mode change .IP \(bu 2 type: file type change .IP \(bu 2 owner: file owner (user/group) change .IP \(bu 2 group: file group change .IP \(bu 2 user: file user change .IP \(bu 2 link: file link change .IP \(bu 2 directory: file directory change .IP \(bu 2 blkdev: file block device change .IP \(bu 2 chrdev: file character device change .IP \(bu 2 fifo: file fifo change .IP \(bu 2 mtime: file modification time change .IP \(bu 2 ctime: file change time change .IP \(bu 2 isomtime: file modification time change (ISO 8601) .IP \(bu 2 isoctime: file creation time change (ISO 8601) .UNINDENT .SS What is compared .sp For each matching item in both archives, Borg reports: .INDENT 0.0 .IP \(bu 2 Content changes: total added/removed bytes within files. If chunker parameters are comparable, Borg compares chunk IDs quickly; otherwise, it compares the content. .IP \(bu 2 Metadata changes: user, group, mode, and other metadata shown inline, like \(dq[old_mode \-> new_mode]\(dq for mode changes. Use \fB\-\-content\-only\fP to suppress metadata changes. .IP \(bu 2 Added/removed items: printed as \(dqadded SIZE path\(dq or \(dqremoved SIZE path\(dq. .UNINDENT .SS Output formats .sp The default (text) output shows one line per changed path, e.g.: .INDENT 0.0 .INDENT 3.5 .sp .EX +135 B \-252 B [ \-rw\-r\-\-r\-\- \-> \-rwxr\-xr\-x ] path/to/file .EE .UNINDENT .UNINDENT .sp JSON Lines output (\fB\-\-json\-lines\fP) prints one JSON object per changed path, e.g.: .INDENT 0.0 .INDENT 3.5 .sp .EX {\(dqpath\(dq: \(dqPATH\(dq, \(dqchanges\(dq: [ {\(dqtype\(dq: \(dqmodified\(dq, \(dqadded\(dq: BYTES, \(dqremoved\(dq: BYTES}, {\(dqtype\(dq: \(dqmode\(dq, \(dqold_mode\(dq: \(dq\-rw\-r\-\-r\-\-\(dq, \(dqnew_mode\(dq: \(dq\-rwxr\-xr\-x\(dq}, {\(dqtype\(dq: \(dqadded\(dq, \(dqsize\(dq: SIZE}, {\(dqtype\(dq: \(dqremoved\(dq, \(dqsize\(dq: SIZE} ]} .EE .UNINDENT .UNINDENT .SS Sorting .sp Use \fB\-\-sort\-by FIELDS\fP where FIELDS is a comma\-separated list of fields. Sorts are applied stably from last to first in the given list. Prepend \(dq>\(dq for descending, \(dq<\(dq (or no prefix) for ascending, for example \fB\-\-sort\-by=\(dq>size_added,path\(dq\fP\&. Supported fields include: .INDENT 0.0 .IP \(bu 2 path: the item path .IP \(bu 2 size_added: total bytes added for the item content .IP \(bu 2 size_removed: total bytes removed for the item content .IP \(bu 2 size_diff: size_added \- size_removed (net content change) .IP \(bu 2 size: size of the item as stored in ARCHIVE2 (0 for removed items) .IP \(bu 2 user, group, uid, gid, ctime, mtime: taken from the item state in ARCHIVE2 when present .IP \(bu 2 ctime_diff, mtime_diff: timestamp difference (ARCHIVE2 \- ARCHIVE1) .UNINDENT .SS Performance considerations .sp diff automatically detects whether the archives were created with the same chunker parameters. If so, only chunk IDs are compared, which is very fast. .SH SEE ALSO .sp \fIborg\-common(1)\fP .SH AUTHOR The Borg Collective .\" Generated by docutils manpage writer. .