Establish a baseline
Scan a directory. Bit Backup calculates file hashes and saves metadata in a local SQLite database.
OPEN-SOURCE FILE INTEGRITY
Bit Backup records SHA-512 fingerprints in a local database and checks them again over time, helping you spot silent corruption in the files you keep.
Local by design MIT licensed Built with C++23
01 / THE IDEA
Files can change without an obvious warning. Bit Backup gives you a local reference point, then compares future scans with that record.
Scan a directory. Bit Backup calculates file hashes and saves metadata in a local SQLite database.
Run it again to compare file contents with the stored record. A full check rehashes files, including those with unchanged modification times.
See detected corruption and lock violations in the terminal, with optional CSV reports for a closer look.
02 / THE TOOLKIT
Start with a complete verification. For large collections, choose how much work each later run should do.
The default full check rehashes files, so corruption can be found even when modification times have not changed.
DEFAULT MODEUse a quick scan or a rotating scrub for large collections. Automatic worker selection adapts to the detected storage type on Linux.
QUICK · SCRUB · THREADSAdd a .bitbackuplock marker after indexing to keep a directory’s saved state fixed and report additions, edits, or deletions.
Exclude paths with .bitbackupignore, export CSV reports and a full file index, and verify the local database with its own checksum.
A check is not a copy. Bit Backup verifies integrity; it does not create or restore backups. Keep separate copies of important files.
03 / RUN MODES
Use a full check for complete coverage on each run, or select how much unchanged data to revisit. Examples assume you have set BIT_BACKUP as shown in Get started and are inside the data directory.
Hashes every tracked file on each run. If file contents change while the modification time stays the same, the changed hash is reported as bit rot.
"$BIT_BACKUP"
Equivalent to "$BIT_BACKUP" check or "$BIT_BACKUP" check scrub=100.
Hashes new files and files whose modification times changed. It usually skips unchanged-time files, so previously unknown silent corruption in those files is not detected on this run.
"$BIT_BACKUP" check quick=true
Equivalent to scrub=0. Locked files and files already marked corrupt are still verified.
Selects the oldest share of stored records for rehashing, while also hashing new and changed-time files. Repeated runs rotate coverage through the collection.
"$BIT_BACKUP" check scrub=25
Choose any percentage from 0 to 100. A positive percentage rounds up to at least one previously indexed file. A 25% scrub does not check every file on that run.
quick=true takes priority over scrub=N and makes it a 0% scrub. Locked files and files already marked corrupt are always hashed. In unlocked directories, a changed modification time is treated as an ordinary edit and its new hash becomes the saved baseline.
04 / CLI REFERENCE
Put options after the explicit check command, separated by spaces: "$BIT_BACKUP" check key=value. Running the executable with no arguments performs a default full check of the current directory. Unknown options and invalid values produce an error.
| Option | Value | Default | What it does |
|---|---|---|---|
dir | Absolute or relative path | Current directory | Chooses the directory to scan and where the local database and reports are stored. Relative paths are resolved from the shell’s working directory. |
quick | true or false | false | With true, skips rehashing unchanged-time, unlocked files unless already marked corrupt. It overrides scrub to 0%. |
scrub | 0–100 | 100 | Selects the oldest N% of stored records for rehashing, rounding up to at least one file when N is positive. 0 is quick behavior; 100 is a full check. |
threads | 1–16 | Automatic | Sets hashing workers manually. On Linux, automatic selection uses 1 for HDD or unknown storage, up to 4 for SSD and up to 16 for NVMe, bounded by available CPUs. |
report | true or false | false | With true, writes .bitbackupreport.csv for detected bit rot. Lock violations are reported in the terminal, not this CSV. |
verbose | true or false | false | Prints more detailed scan information, including file listings. |
bitbackupindex | true or false | false | With true, writes .bitbackupindex.csv containing each included file’s relative path, size in bytes, and SHA-512 hash. |
confirm | delete | Off | Interactively asks whether to remove each deleted locked file from the stored database. It does not confirm modified or newly added files. |
Directory paths. dir=/path/to/data selects a collection regardless of the shell’s current directory. Bit Backup writes its metadata and requested CSV files into the selected directory.
Index cost. An index run hashes every included file to produce its SHA-512 column. This extra read happens even with quick=true or a partial scrub.
EXAMPLE COMMANDS
The commands below use the executable path set during the build steps.
"$BIT_BACKUP" check verbose=true report=trueRehash every file, print detailed progress, and write a CSV report of any bit rot.
"$BIT_BACKUP" check scrub=20 threads=8Recheck the oldest 20% of unchanged-time files with eight hashing workers.
"$BIT_BACKUP" check confirm=deleteAfter a locked file is deleted, answer each prompt to keep its violation or remove its saved row.
"$BIT_BACKUP" check dir=/path/to/data report=trueScan a chosen path from elsewhere. Both the bit-rot report and integrity database are written into that directory.
"$BIT_BACKUP" check bitbackupindex=trueCreate .bitbackupindex.csv with relative path, byte size and current SHA-512 hash for each included file.
"$BIT_BACKUP" help
"$BIT_BACKUP" versionShow the built-in usage text or the current version string without running a file check.
05 / IN PRACTICE
A few operational details help you interpret the result and keep your baseline useful.
The first run records hashes. Later runs add new files and update the stored hash of an unlocked file whose modification time changed. Bit rot is flagged when a full or partial check finds different content with an unchanged modification time.
Index the files first, then add an empty .bitbackuplock file in the directory to freeze it. Subsequent runs keep saved hashes and timestamps fixed, and report modified, new, or deleted files in that subtree. Remove the marker to resume normal updates.
touch archive/.bitbackuplock
"$BIT_BACKUP" checkPlace .bitbackupignore in the scanned root. Patterns support *, ?, root-anchored paths such as /logs/, directory rules ending in /, and ! to re-include a path. Bit Backup metadata remains excluded even with a ! rule. Only the root ignore file is loaded.
/logs/
*.tmp
!important.tmpThe directory holds .bitbackup.sqlite3 and its .sha512 checksum. report=true adds a CSV for bit rot. A check exits with a nonzero code when it detects bit rot or a lock violation, making it usable in scripts.
06 / GET STARTED
Build from source, move into the directory you want to monitor, and run your first check. Later runs compare against the local record.
A C++23 compiler, CMake 3.25+, OpenSSL, and SQLite3. The SQLiteCpp dependency is included as a Git submodule.
git clone --recurse-submodules https://github.com/robertvokac/bit-backup.git
cd bit-backup
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --config Release
BIT_BACKUP="$PWD/build/bit_backup"
cd /path/to/data
"$BIT_BACKUP"
Replace /path/to/data with your directory. By default, bit_backup checks the current directory. Run it again later to verify the saved baseline.