treesum

Description

Overall Format

The overall file format classifies as follows:

  • It is a text file.

  • Lines are terminated by a single U+000A character, a single U+000D character, or the two-character combination carriage return and line feed (U+000D U+000A). The last line shall be terminated likewise.

    Different newline markers can be mixed freely.

  • Empty lines, lines consisting only of the whitespace characters space (U+0020) and horizontal tabulators (U+0009) are completely ignored (except for counting lines).

  • Likewise ignored are (user) comment lines, lines where the first non-whitespace character is either a the number sign # (U+0023) or a semicolon ; (U+003B).

    But note the difference to COMMENT (see here).

  • All other lines are records.

    Records come in two flavours: “tagged” (BSD style) and “tabular” (GNU style). For a comparison see this section.

  • Records are grouped into blocks semantically.

    A single treesum data file may contain several blocks.

Blocks

A “block” is a group of records.

Every DIRECTORY on the command line becomes a “block” in the output. So a “block” describes what is the essence of py-treesum: a message digest of a directory tree.

Every block starts with a VERSION record and regularly ends with a CRC32 record. If the CRC32 record is missing a block ends at EOF or at the next VERSION record in the data—which ends the current block and starts a new block.

The primary encoding of a block is either UTF-8 or the encoding given in the block’s FSENCODING record. This is documented in the FLAGS record. Note that the primary encoding of the content may differ from block to block.

All records of a block must share a consistent single flavour “tagged” or “tabular”. Different blocks may have different record flavours.

Records in Lines: “tagged” vs “tabular”

Note

Horizontal tabular characters (U+0009) are printed here as “␉” glyphs.

In the “tabular” format each record consists of two or more TAB-separated columns. The record’s name or type may be derived from the number of colums or other context data.

In the “tagged” format each record (aka line) begins with the record’s name or type, which is unique.

Record NAME

“tagged”

“tabular”

VERSION, CRC32, FSENCODING, GENERATOR, FLAGS, START-TIMESTAMP, END-TIMESTAMP, COMMENT, FNMATCH

NAME = VALUE
NAME ␉ VALUE

ROOT

ROOT(PATH)
ROOT ␉ PATH

ACCEPT-TREESUM

ACCEPT-TREESUM(PATH) = FILE
ACCEPT-TREESUM:FILE ␉ {PATH}
ACCEPT-TREESUM:FILE ␉ ␉ {PATH}

ERROR

ERROR(PATH) = MESSAGE
ERR:MESSAGE ␉ PATH
ERR:MESSAGE ␉ ///// ␉ PATH

WARNING

WARNING(PATH) = MESSAGE
WARN:MESSAGE ␉ PATH
WARN:MESSAGE ␉ ///// ␉ PATH

NOTE

NOTE(PATH) = MESSAGE
NOTE:MESSAGE ␉ PATH
NOTE:MESSAGE ␉ ///// ␉ PATH

SIZE

SIZE(PATH) = SZ
SIZE(PATH)
SZ ␉ PATH

DIGEST

DIGEST(PATH) = VALUE
DIGEST(PATH) = VALUE,SZ
DIGEST(PATH)
DIGEST:VALUE ␉ PATH
DIGEST:VALUE ␉ SZ ␉ PATH

Some additional notes:

  • In “tabular” flavour all SZ values may be numbers, or—in error cases—a sequence of slash characters / (e.g. ////////).

  • In “tagged” style all SZ values also may be the empty string.

Records

VERSION

Required to start a block and to declare its format version.

Currently the version value is 1.

The current block regularly ends with a CRC32 record or—if this is missing—at EOF or the next VERSION record in the data.

CRC32

The CRC checksum regularly ends the current block.

It is the hex-encoded CRC-32 (as used in Ethernet, ZIP, PNG et al.) of all the lines of the block as seen in the input, using the normalized newline character Unicode code point U+000A on all operating systems.

(User) comment lines (first non-whitespace is # or ;), lines consisting of whitespace characters (tabs and spaces) only and empty lines do not contribute to the CRC. These lines are ignored with the exception of contributing to line numbering.

FSENCODING

The result of sys.getfilesystemencoding() that is in effect when generating treesum digests (process environment)

GENERATOR

The existence of this record and its value depends on the option --generator:

full yields full Python and OS/platform version information.

normal gives just the version of py-treesum and whether Python 2 or Python 3 is used.

With none the record will not be found in the output at all.

FLAGS

A comma-separated list of flag values (strings).

They reflect important settings that were in effect when the current block has been generated.

Possible Flag Value

Always

Description

denc-ENCODING

✓

Encoding of message digests. Possible values of ENCODING are hex, base32, base64, base85 and rfc1924.

fs-encoding, utf8-encoding

✓

Denote whether either sys.getfilesystemencoding() (as recorded in the FSENCODING record) or utf-8 are the primary encoding of all the records of the current block. This affects primarily path names, but also all other “text” values like error messages, filter expressions and comment records. Message digest values are not affected.

follow-symlinks-commandline, no-follow-symlinks-commandline

✓

Symlink handling for command line arguments

follow-symlinks-directory, no-follow-symlinks-directory

✓

Symlink handling for directories

follow-symlinks-file, no-follow-symlinks-file

✓

Symlink handling for non-directories

ignore-symlink-type, no-ignore-symlink-type

✓

Reflect whether --ignore-symlink-type or --no-ignore-symlink-type was in effect when the treesum block data was generated.

print-size

--print-size was also given and—additionally to message digests—file sizes and accumulated file sizes for directory trees are in the block data; the values of message digests are not affected in any way.

size-only

--size-only was given: no digests but only file sizes and accumulated file sizes for directory trees are in the block’s data.

with-metadata-fullmode

--full-mode was in effect: all all mode bits as returned from stat(2) were used in digest computations for directory message digests.

with-metadata-mode

--mode was in effect: the permission bits of stat(2) using S_IMODE (i.e. all bits without the filetype bits) contributed to directory message digests.

with-metadata-mtime

--mtime was in effect: the mtime as ISO string formatted timestamp (truncated to seconds) was used in message digest computations also.

with-notes

--with-notes was in effect

without-warnings

--without-warnings was in effect

A “✓” character in the “Always” column denotes a flag where one of its possible values is always there. Otherwise a “missing” flag denotes a default value.

START-TIMESTAMP, END-TIMESTAMP

Contain the start and end times of py-treesum generate in Unix epoch time and as ISO formatted string (truncated to seconds).

These records are generated only if --minimal is not given.

COMMENT

Contains the value of a --comment option.

Its existence depends on --minimal.

FNMATCH

Remembers the option values for options --include, --exclude and --accept-treesum.

ROOT

By default contains the root of the block’s directory tree as given on the command line—but somewhat normalized.

If --minimal=VALUE is used then VALUE is put into the ROOT record.

SIZE

If --print-size is used it replaces DIGEST records. See also there.

ERROR, WARNING, NOTE

These records contain non-fatal errors, warnings or other notes for a given PATH as text messages. Their individual message formats are somewhat unspecific.

ACCEPT-TREESUM

Note that a message digest has been accepted for a given PATH from a within file FILE.

Precedes the accepted message digest or size record.

DIGEST

The last digest record is the aggregated message digest of the current block. Its PATH values and file types differ from the other file types given in other records.

For more details see file types.

Note that this is true also for associated records (e.g. ERROR, WARNING, NOTE, ACCEPT-TREESUM).

Examples

py-treesum generate -P -a md5 --base85 --utf8 --print-size --with-notes -X $'re:\\.(treesum|size)\\Z' yields:

VERSION = 1
FSENCODING = UTF-8
GENERATOR = treesum 0.13.dev1 (PY3)
FLAGS = denc-base85,ignore-symlink-type,no-follow-symlinks-commandline,no-follow-symlinks-directory,no-follow-symlinks-file,print-size,utf8-encoding,with-notes
START-TIMESTAMP = 1789643152;2026-09-17T11:05:52+00:00
COMMENT = These are comment records ...
COMMENT = ... with german umlauts: ÄÖÜäöüß
FNMATCH = exclude: re:\.(treesum|size)\Z
ROOT (tests/data)
NOTE (_data-tabular.size) = SKIPPED
NOTE (_data-tabular.treesum) = SKIPPED
NOTE (_data.size) = SKIPPED
NOTE (_data.treesum) = SKIPPED
MD5 (cp1252/ED K�hlen Unterbau integrierbar.txt) = rdj)Q97HI{^?bhm%WeIQ,286
MD5 (cp1252/) = pjtI_`Yx-{HTq^}yqTnq,286
MD5 (empty) = )E$i3j{vd+>3|8C?D#@{,0
MD5 (tree-1/file-1-1-s.txt/./@@) = xA6W44p|6H{6tP9JprW>,
MD5 (tree-1/file-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-1/file-1-2.txt) = <QM)?xn^5^_Up8I<;!xk,5
MD5 (tree-1/file-1-nn-s.txt/./@@) = F;c0D<LA(a2Mj(WrL%Wo,
MD5 (tree-1/) = `NK5R_pX){M<jO6yFOxM,8
MD5 (tree-1-s/./@@) = -rMfx(}?S@lFsC9IN}!m,
MD5 (tree-2/empty-1) = )E$i3j{vd+>3|8C?D#@{,0
MD5 (tree-2/tree-1-s/./@@) = sl4wU;GXSMxPghs&)C&o,
MD5 (tree-2/tree-nn-s/./@@) = mFx)c&pW$k?~hS^q4hE$,
MD5 (tree-2/) = y+*qfv6XmbQvYh$fIrLK,0
MD5 (tree-3/file-3-1.txt) = fhu7XpG26sQ_f0!I@JzX,7
MD5 (tree-3/file-3-2.txt) = 4Ty2f_BHQFdx)=lBhCv;,10
MD5 (tree-3/tree-3-1/file-3-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-3/tree-3-1/file-3-1-2-s.txt/./@@) = jxXVFC38i7tb=hEE69m`,
MD5 (tree-3/tree-3-1/file-3-1-2.txt) = dj!jZf05z5j#3HG%d1Zm,9
MD5 (tree-3/tree-3-1/) = i7uW7{WVGHq0a8D<1)G6,12
MD5 (tree-3/tree-3-1-s/./@@) = ;~R1N3IuJ%8mBVV5L%Jq,
MD5 (tree-3/) = CM3DuI89j$0)?_!K%Q^P,29
MD5 (tree-3-2/file-3-2-1.txt) = 9{WI}+N+I|usA%X%%pia,9
MD5 (tree-3-2/file-3-2-2.txt) = 8V#2oGG88-Mqa0$?)0x<,9
MD5 (tree-3-2/) = z|rebkV4<IP>7{KFe4o+,18
MD5 (tree-nn-s/./@@) = >2z{C+9T3isrfNL)Xwny,
MD5 (utf-8/ED Kühlen Unterbau integrierbar.txt) = rdj)Q97HI{^?bhm%WeIQ,286
MD5 (utf-8/) = $Wrg`kGIKcrARWc`}^&i,286
MD5 () = cM@)n*}De!OLW`ZbhhMv,627
END-TIMESTAMP = 1789643152;2026-09-17T11:05:52+00:00
CRC32 = E265C939

The same directory tree in the tabular output format using py-treesum generate -P -a md5 --base85 --utf8 --print-size --with-notes -X $'re:\\.(treesum|size)\\Z' --reverse --size-width=4 yields:

VERSION	1
FSENCODING	UTF-8
GENERATOR	treesum 0.13.dev1 (PY3)
FLAGS	denc-base85,ignore-symlink-type,no-follow-symlinks-commandline,no-follow-symlinks-directory,no-follow-symlinks-file,print-size,utf8-encoding,with-notes
START-TIMESTAMP	1789643152;2026-09-17T11:05:52+00:00
COMMENT	These are comment records ...
COMMENT	... with german umlauts: ÄÖÜäöüß
FNMATCH	exclude: re:\.(treesum|size)\Z
ROOT	tests/data
NOTE:SKIPPED            	////	_data-tabular.size
NOTE:SKIPPED            	////	_data-tabular.treesum
NOTE:SKIPPED            	////	_data.size
NOTE:SKIPPED            	////	_data.treesum
MD5:rdj)Q97HI{^?bhm%WeIQ	 286	cp1252/ED K�hlen Unterbau integrierbar.txt
MD5:pjtI_`Yx-{HTq^}yqTnq	 286	cp1252/
MD5:)E$i3j{vd+>3|8C?D#@{	   0	empty
MD5:xA6W44p|6H{6tP9JprW>	    	tree-1/file-1-1-s.txt/./@@
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-1/file-1-1.txt
MD5:<QM)?xn^5^_Up8I<;!xk	   5	tree-1/file-1-2.txt
MD5:F;c0D<LA(a2Mj(WrL%Wo	    	tree-1/file-1-nn-s.txt/./@@
MD5:`NK5R_pX){M<jO6yFOxM	   8	tree-1/
MD5:-rMfx(}?S@lFsC9IN}!m	    	tree-1-s/./@@
MD5:)E$i3j{vd+>3|8C?D#@{	   0	tree-2/empty-1
MD5:sl4wU;GXSMxPghs&)C&o	    	tree-2/tree-1-s/./@@
MD5:mFx)c&pW$k?~hS^q4hE$	    	tree-2/tree-nn-s/./@@
MD5:y+*qfv6XmbQvYh$fIrLK	   0	tree-2/
MD5:fhu7XpG26sQ_f0!I@JzX	   7	tree-3/file-3-1.txt
MD5:4Ty2f_BHQFdx)=lBhCv;	  10	tree-3/file-3-2.txt
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-3/tree-3-1/file-3-1-1.txt
MD5:jxXVFC38i7tb=hEE69m`	    	tree-3/tree-3-1/file-3-1-2-s.txt/./@@
MD5:dj!jZf05z5j#3HG%d1Zm	   9	tree-3/tree-3-1/file-3-1-2.txt
MD5:i7uW7{WVGHq0a8D<1)G6	  12	tree-3/tree-3-1/
MD5:;~R1N3IuJ%8mBVV5L%Jq	    	tree-3/tree-3-1-s/./@@
MD5:CM3DuI89j$0)?_!K%Q^P	  29	tree-3/
MD5:9{WI}+N+I|usA%X%%pia	   9	tree-3-2/file-3-2-1.txt
MD5:8V#2oGG88-Mqa0$?)0x<	   9	tree-3-2/file-3-2-2.txt
MD5:z|rebkV4<IP>7{KFe4o+	  18	tree-3-2/
MD5:>2z{C+9T3isrfNL)Xwny	    	tree-nn-s/./@@
MD5:rdj)Q97HI{^?bhm%WeIQ	 286	utf-8/ED Kühlen Unterbau integrierbar.txt
MD5:$Wrg`kGIKcrARWc`}^&i	 286	utf-8/
MD5:cM@)n*}De!OLW`ZbhhMv	 627	.
END-TIMESTAMP	1789643152;2026-09-17T11:05:52+00:00
CRC32	9FE07B69

Logical traversal with resolving all symbolic links should give errors.

py-treesum generate -L -a md5 --base85 --utf8 --print-size --with-notes -X $'re:\\.(treesum|size)\\Z' :

VERSION = 1
FSENCODING = UTF-8
GENERATOR = treesum 0.13.dev1 (PY3)
FLAGS = denc-base85,follow-symlinks-commandline,follow-symlinks-directory,follow-symlinks-file,ignore-symlink-type,print-size,utf8-encoding,with-notes
START-TIMESTAMP = 1789643152;2026-09-17T11:05:52+00:00
COMMENT = These are comment records ...
COMMENT = ... with german umlauts: ÄÖÜäöüß
FNMATCH = exclude: re:\.(treesum|size)\Z
ROOT (tests/data)
NOTE (_data-tabular.size) = SKIPPED
NOTE (_data-tabular.treesum) = SKIPPED
NOTE (_data.size) = SKIPPED
NOTE (_data.treesum) = SKIPPED
MD5 (cp1252/ED K�hlen Unterbau integrierbar.txt) = rdj)Q97HI{^?bhm%WeIQ,286
MD5 (cp1252/) = pjtI_`Yx-{HTq^}yqTnq,286
MD5 (empty) = )E$i3j{vd+>3|8C?D#@{,0
MD5 (tree-1/file-1-1-s.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-1/file-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-1/file-1-2.txt) = <QM)?xn^5^_Up8I<;!xk,5
ERROR (tree-1/file-1-nn-s.txt) = errno 2: No such file or directory
MD5 (tree-1/file-1-nn-s.txt)
ERROR (tree-1/) = directory is TAINTED
MD5 (tree-1/) = =#gafTrUE9_}PX%MQn$a,11
MD5 (tree-1-s/file-1-1-s.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-1-s/file-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-1-s/file-1-2.txt) = <QM)?xn^5^_Up8I<;!xk,5
ERROR (tree-1-s/file-1-nn-s.txt) = errno 2: No such file or directory
MD5 (tree-1-s/file-1-nn-s.txt)
ERROR (tree-1-s/) = directory is TAINTED
MD5 (tree-1-s/) = =#gafTrUE9_}PX%MQn$a,11
MD5 (tree-2/empty-1) = )E$i3j{vd+>3|8C?D#@{,0
MD5 (tree-2/tree-1-s/file-1-1-s.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-2/tree-1-s/file-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-2/tree-1-s/file-1-2.txt) = <QM)?xn^5^_Up8I<;!xk,5
ERROR (tree-2/tree-1-s/file-1-nn-s.txt) = errno 2: No such file or directory
MD5 (tree-2/tree-1-s/file-1-nn-s.txt)
ERROR (tree-2/tree-1-s/) = directory is TAINTED
MD5 (tree-2/tree-1-s/) = =#gafTrUE9_}PX%MQn$a,11
ERROR (tree-2/tree-nn-s) = errno 2: No such file or directory
MD5 (tree-2/tree-nn-s)
ERROR (tree-2/) = directory is TAINTED
MD5 (tree-2/) = adrm!^zJ%ugryYci#Un2,11
MD5 (tree-3/file-3-1.txt) = fhu7XpG26sQ_f0!I@JzX,7
MD5 (tree-3/file-3-2.txt) = 4Ty2f_BHQFdx)=lBhCv;,10
MD5 (tree-3/tree-3-1/file-3-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-3/tree-3-1/file-3-1-2-s.txt) = dj!jZf05z5j#3HG%d1Zm,9
MD5 (tree-3/tree-3-1/file-3-1-2.txt) = dj!jZf05z5j#3HG%d1Zm,9
MD5 (tree-3/tree-3-1/) = u^fJ=eCeXqi!AkaFtPQH,21
MD5 (tree-3/tree-3-1-s/file-3-1-1.txt) = @AbSM`0Skn=0N;IaP{iV,3
MD5 (tree-3/tree-3-1-s/file-3-1-2-s.txt) = dj!jZf05z5j#3HG%d1Zm,9
MD5 (tree-3/tree-3-1-s/file-3-1-2.txt) = dj!jZf05z5j#3HG%d1Zm,9
MD5 (tree-3/tree-3-1-s/) = u^fJ=eCeXqi!AkaFtPQH,21
MD5 (tree-3/) = 8zx|;lgJ(!6?1{{)<cr{,59
MD5 (tree-3-2/file-3-2-1.txt) = 9{WI}+N+I|usA%X%%pia,9
MD5 (tree-3-2/file-3-2-2.txt) = 8V#2oGG88-Mqa0$?)0x<,9
MD5 (tree-3-2/) = z|rebkV4<IP>7{KFe4o+,18
ERROR (tree-nn-s) = errno 2: No such file or directory
MD5 (tree-nn-s)
MD5 (utf-8/ED Kühlen Unterbau integrierbar.txt) = rdj)Q97HI{^?bhm%WeIQ,286
MD5 (utf-8/) = $Wrg`kGIKcrARWc`}^&i,286
ERROR () = directory is TAINTED
MD5 () = ZW|qu`w&7sY2+F;==OsA,682
END-TIMESTAMP = 1789643152;2026-09-17T11:05:52+00:00
CRC32 = 28EF9843

py-treesum generate -L -a md5 --base85 --utf8 --print-size --with-notes -X $'re:\\.(treesum|size)\\Z' --reverse --size-width=4 :

VERSION	1
FSENCODING	UTF-8
GENERATOR	treesum 0.13.dev1 (PY3)
FLAGS	denc-base85,follow-symlinks-commandline,follow-symlinks-directory,follow-symlinks-file,ignore-symlink-type,print-size,utf8-encoding,with-notes
START-TIMESTAMP	1789643152;2026-09-17T11:05:52+00:00
COMMENT	These are comment records ...
COMMENT	... with german umlauts: ÄÖÜäöüß
FNMATCH	exclude: re:\.(treesum|size)\Z
ROOT	tests/data
NOTE:SKIPPED            	////	_data-tabular.size
NOTE:SKIPPED            	////	_data-tabular.treesum
NOTE:SKIPPED            	////	_data.size
NOTE:SKIPPED            	////	_data.treesum
MD5:rdj)Q97HI{^?bhm%WeIQ	 286	cp1252/ED K�hlen Unterbau integrierbar.txt
MD5:pjtI_`Yx-{HTq^}yqTnq	 286	cp1252/
MD5:)E$i3j{vd+>3|8C?D#@{	   0	empty
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-1/file-1-1-s.txt
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-1/file-1-1.txt
MD5:<QM)?xn^5^_Up8I<;!xk	   5	tree-1/file-1-2.txt
ERR:errno 2: No such file or directory	////	tree-1/file-1-nn-s.txt
MD5:////////////////////	////	tree-1/file-1-nn-s.txt
ERR:directory is TAINTED	////	tree-1/
MD5:=#gafTrUE9_}PX%MQn$a	  11	tree-1/
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-1-s/file-1-1-s.txt
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-1-s/file-1-1.txt
MD5:<QM)?xn^5^_Up8I<;!xk	   5	tree-1-s/file-1-2.txt
ERR:errno 2: No such file or directory	////	tree-1-s/file-1-nn-s.txt
MD5:////////////////////	////	tree-1-s/file-1-nn-s.txt
ERR:directory is TAINTED	////	tree-1-s/
MD5:=#gafTrUE9_}PX%MQn$a	  11	tree-1-s/
MD5:)E$i3j{vd+>3|8C?D#@{	   0	tree-2/empty-1
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-2/tree-1-s/file-1-1-s.txt
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-2/tree-1-s/file-1-1.txt
MD5:<QM)?xn^5^_Up8I<;!xk	   5	tree-2/tree-1-s/file-1-2.txt
ERR:errno 2: No such file or directory	////	tree-2/tree-1-s/file-1-nn-s.txt
MD5:////////////////////	////	tree-2/tree-1-s/file-1-nn-s.txt
ERR:directory is TAINTED	////	tree-2/tree-1-s/
MD5:=#gafTrUE9_}PX%MQn$a	  11	tree-2/tree-1-s/
ERR:errno 2: No such file or directory	////	tree-2/tree-nn-s
MD5:////////////////////	////	tree-2/tree-nn-s
ERR:directory is TAINTED	////	tree-2/
MD5:adrm!^zJ%ugryYci#Un2	  11	tree-2/
MD5:fhu7XpG26sQ_f0!I@JzX	   7	tree-3/file-3-1.txt
MD5:4Ty2f_BHQFdx)=lBhCv;	  10	tree-3/file-3-2.txt
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-3/tree-3-1/file-3-1-1.txt
MD5:dj!jZf05z5j#3HG%d1Zm	   9	tree-3/tree-3-1/file-3-1-2-s.txt
MD5:dj!jZf05z5j#3HG%d1Zm	   9	tree-3/tree-3-1/file-3-1-2.txt
MD5:u^fJ=eCeXqi!AkaFtPQH	  21	tree-3/tree-3-1/
MD5:@AbSM`0Skn=0N;IaP{iV	   3	tree-3/tree-3-1-s/file-3-1-1.txt
MD5:dj!jZf05z5j#3HG%d1Zm	   9	tree-3/tree-3-1-s/file-3-1-2-s.txt
MD5:dj!jZf05z5j#3HG%d1Zm	   9	tree-3/tree-3-1-s/file-3-1-2.txt
MD5:u^fJ=eCeXqi!AkaFtPQH	  21	tree-3/tree-3-1-s/
MD5:8zx|;lgJ(!6?1{{)<cr{	  59	tree-3/
MD5:9{WI}+N+I|usA%X%%pia	   9	tree-3-2/file-3-2-1.txt
MD5:8V#2oGG88-Mqa0$?)0x<	   9	tree-3-2/file-3-2-2.txt
MD5:z|rebkV4<IP>7{KFe4o+	  18	tree-3-2/
ERR:errno 2: No such file or directory	////	tree-nn-s
MD5:////////////////////	////	tree-nn-s
MD5:rdj)Q97HI{^?bhm%WeIQ	 286	utf-8/ED Kühlen Unterbau integrierbar.txt
MD5:$Wrg`kGIKcrARWc`}^&i	 286	utf-8/
ERR:directory is TAINTED	////	.
MD5:ZW|qu`w&7sY2+F;==OsA	 682	.
END-TIMESTAMP	1789643152;2026-09-17T11:05:52+00:00
CRC32	F73EB8FA

Printing only the sizes gives these results …

… for tagged output using py-treesum generate -L -a md5 --base85 --utf8 --size-only --with-notes -X $'re:\\.(treesum|size)\\Z' :

VERSION = 1
FSENCODING = UTF-8
GENERATOR = treesum 0.13.dev1 (PY3)
FLAGS = denc-base85,follow-symlinks-commandline,follow-symlinks-directory,follow-symlinks-file,ignore-symlink-type,size-only,utf8-encoding,with-notes
START-TIMESTAMP = 1789643152;2026-09-17T11:05:52+00:00
COMMENT = These are comment records ...
COMMENT = ... with german umlauts: ÄÖÜäöüß
FNMATCH = exclude: re:\.(treesum|size)\Z
ROOT (tests/data)
NOTE (_data-tabular.size) = SKIPPED
NOTE (_data-tabular.treesum) = SKIPPED
NOTE (_data.size) = SKIPPED
NOTE (_data.treesum) = SKIPPED
SIZE (cp1252/ED K�hlen Unterbau integrierbar.txt) = 286
SIZE (cp1252/) = 286
SIZE (empty) = 0
SIZE (tree-1/file-1-1-s.txt) = 3
SIZE (tree-1/file-1-1.txt) = 3
SIZE (tree-1/file-1-2.txt) = 5
ERROR (tree-1/file-1-nn-s.txt) = errno 2: No such file or directory
SIZE (tree-1/file-1-nn-s.txt)
ERROR (tree-1/) = directory is TAINTED
SIZE (tree-1/) = 11
SIZE (tree-1-s/file-1-1-s.txt) = 3
SIZE (tree-1-s/file-1-1.txt) = 3
SIZE (tree-1-s/file-1-2.txt) = 5
ERROR (tree-1-s/file-1-nn-s.txt) = errno 2: No such file or directory
SIZE (tree-1-s/file-1-nn-s.txt)
ERROR (tree-1-s/) = directory is TAINTED
SIZE (tree-1-s/) = 11
SIZE (tree-2/empty-1) = 0
SIZE (tree-2/tree-1-s/file-1-1-s.txt) = 3
SIZE (tree-2/tree-1-s/file-1-1.txt) = 3
SIZE (tree-2/tree-1-s/file-1-2.txt) = 5
ERROR (tree-2/tree-1-s/file-1-nn-s.txt) = errno 2: No such file or directory
SIZE (tree-2/tree-1-s/file-1-nn-s.txt)
ERROR (tree-2/tree-1-s/) = directory is TAINTED
SIZE (tree-2/tree-1-s/) = 11
ERROR (tree-2/tree-nn-s) = errno 2: No such file or directory
SIZE (tree-2/tree-nn-s)
ERROR (tree-2/) = directory is TAINTED
SIZE (tree-2/) = 11
SIZE (tree-3/file-3-1.txt) = 7
SIZE (tree-3/file-3-2.txt) = 10
SIZE (tree-3/tree-3-1/file-3-1-1.txt) = 3
SIZE (tree-3/tree-3-1/file-3-1-2-s.txt) = 9
SIZE (tree-3/tree-3-1/file-3-1-2.txt) = 9
SIZE (tree-3/tree-3-1/) = 21
SIZE (tree-3/tree-3-1-s/file-3-1-1.txt) = 3
SIZE (tree-3/tree-3-1-s/file-3-1-2-s.txt) = 9
SIZE (tree-3/tree-3-1-s/file-3-1-2.txt) = 9
SIZE (tree-3/tree-3-1-s/) = 21
SIZE (tree-3/) = 59
SIZE (tree-3-2/file-3-2-1.txt) = 9
SIZE (tree-3-2/file-3-2-2.txt) = 9
SIZE (tree-3-2/) = 18
ERROR (tree-nn-s) = errno 2: No such file or directory
SIZE (tree-nn-s)
SIZE (utf-8/ED Kühlen Unterbau integrierbar.txt) = 286
SIZE (utf-8/) = 286
ERROR () = directory is TAINTED
SIZE () = 682
END-TIMESTAMP = 1789643152;2026-09-17T11:05:52+00:00
CRC32 = F18A7519

… for tabular output using py-treesum generate -L -a md5 --base85 --utf8 --size-only --with-notes -X $'re:\\.(treesum|size)\\Z' --reverse --size-width=4 :

VERSION	1
FSENCODING	UTF-8
GENERATOR	treesum 0.13.dev1 (PY3)
FLAGS	denc-base85,follow-symlinks-commandline,follow-symlinks-directory,follow-symlinks-file,ignore-symlink-type,size-only,utf8-encoding,with-notes
START-TIMESTAMP	1789643152;2026-09-17T11:05:52+00:00
COMMENT	These are comment records ...
COMMENT	... with german umlauts: ÄÖÜäöüß
FNMATCH	exclude: re:\.(treesum|size)\Z
ROOT	tests/data
NOTE:SKIPPED            	_data-tabular.size
NOTE:SKIPPED            	_data-tabular.treesum
NOTE:SKIPPED            	_data.size
NOTE:SKIPPED            	_data.treesum
 286	cp1252/ED K�hlen Unterbau integrierbar.txt
 286	cp1252/
   0	empty
   3	tree-1/file-1-1-s.txt
   3	tree-1/file-1-1.txt
   5	tree-1/file-1-2.txt
ERR:errno 2: No such file or directory	tree-1/file-1-nn-s.txt
////	tree-1/file-1-nn-s.txt
ERR:directory is TAINTED	tree-1/
  11	tree-1/
   3	tree-1-s/file-1-1-s.txt
   3	tree-1-s/file-1-1.txt
   5	tree-1-s/file-1-2.txt
ERR:errno 2: No such file or directory	tree-1-s/file-1-nn-s.txt
////	tree-1-s/file-1-nn-s.txt
ERR:directory is TAINTED	tree-1-s/
  11	tree-1-s/
   0	tree-2/empty-1
   3	tree-2/tree-1-s/file-1-1-s.txt
   3	tree-2/tree-1-s/file-1-1.txt
   5	tree-2/tree-1-s/file-1-2.txt
ERR:errno 2: No such file or directory	tree-2/tree-1-s/file-1-nn-s.txt
////	tree-2/tree-1-s/file-1-nn-s.txt
ERR:directory is TAINTED	tree-2/tree-1-s/
  11	tree-2/tree-1-s/
ERR:errno 2: No such file or directory	tree-2/tree-nn-s
////	tree-2/tree-nn-s
ERR:directory is TAINTED	tree-2/
  11	tree-2/
   7	tree-3/file-3-1.txt
  10	tree-3/file-3-2.txt
   3	tree-3/tree-3-1/file-3-1-1.txt
   9	tree-3/tree-3-1/file-3-1-2-s.txt
   9	tree-3/tree-3-1/file-3-1-2.txt
  21	tree-3/tree-3-1/
   3	tree-3/tree-3-1-s/file-3-1-1.txt
   9	tree-3/tree-3-1-s/file-3-1-2-s.txt
   9	tree-3/tree-3-1-s/file-3-1-2.txt
  21	tree-3/tree-3-1-s/
  59	tree-3/
   9	tree-3-2/file-3-2-1.txt
   9	tree-3-2/file-3-2-2.txt
  18	tree-3-2/
ERR:errno 2: No such file or directory	tree-nn-s
////	tree-nn-s
 286	utf-8/ED Kühlen Unterbau integrierbar.txt
 286	utf-8/
ERR:directory is TAINTED	.
 682	.
END-TIMESTAMP	1789643152;2026-09-17T11:05:52+00:00
CRC32	D9B25DFC

See Also

py-treesum, file type indicators

Bugs

Version 1 of the file format may change in versions of py-treesum before version 1.0; backwards compatibility is not really retained before version 1.0.