Scanning and hashing are the two steps that let Kopia Desk decide which files need to be copied on any given backup run. Scanning builds a flat map of every file under a directory, and hashing verifies whether a file’s content has actually changed since the last backup. Both operations live inDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/Pachanga12/Kopia_Desk_Beta_1/llms.txt
Use this file to discover all available pages before exploring further.
lib/core.js so they can be tested without Electron; main.js registers each one as an IPC handler and delegates to the core functions directly.
All scan and hash operations use fs.promises (async I/O) instead of synchronous equivalents, so the Electron main process—and therefore the UI window—stays responsive even while traversing large directory trees or reading multi-gigabyte files.
scanDirectory(dirPath, excludePatterns)
Recursively walks dirPath and returns a flat map of every reachable file, keyed by its path relative to dirPath. Directories and files whose names match any pattern in excludePatterns are skipped entirely (including their contents). Entries inside protected Windows folders (EPERM) are silently omitted rather than causing the whole scan to fail.
Absolute path to the directory to scan. The IPC handler checks
fs.existsSync(dirPath) before calling into lib/core.js and throws "La carpeta no existe: <dirPath>" if the directory is not present.Glob-style patterns (supporting
* and ?) matched case-insensitively against each entry’s name. Defaults to DEFAULT_EXCLUDES when omitted or empty. See defaultExcludePatterns() for the full list.Promise<FileMap> where FileMap = { [relativePath: string]: FileEntry }
Each key is the file’s path relative to
dirPath, using forward-slash separators (e.g. "vacation/beach.jpg").defaultExcludePatterns()
Returns the DEFAULT_EXCLUDES constant exported by lib/core.js. The UI uses this to pre-populate the exclusion list shown to the user before a backup run.
Parameters: none
Returns: Promise<string[]>
The array returned is always:
* (any sequence of characters) and ? (any single character). Matching is case-insensitive. Pass this array—or a modified copy—as excludePatterns to scanDirectory().
hashFile(filePath)
Computes the full SHA-256 digest of a file by streaming its entire content through Node’s crypto.createHash. This is the accurate hash used when the user enables the “deep verification” option; it is slower than quickHashFile() for large files but guarantees that even a single changed byte is detected.
Absolute path to the file to hash.
Promise<string> — lowercase hexadecimal SHA-256 digest (64 characters).
quickHashFile(filePath, size)
Produces a SHA-256 digest from only the first and last 64 KB of the file, with the file size encoded as a string prefix in the hash input. This makes the hash sensitive to size changes, header/trailer changes, and most content edits, while reading at most 128 KB per file regardless of total size.
The exact algorithm in lib/core.js:
- Hash input is initialised with
String(size)as a prefix. - Read up to
CHUNK(65 536) bytes from offset 0 (the head). - If
size > CHUNK, also read up toCHUNKbytes from offsetsize - CHUNK(the tail). - Return
hash.digest('hex').
Absolute path to the file to hash.
File size in bytes. Must match the actual file size; it is included in the hash computation so that two files with identical head+tail but different lengths produce different digests.
Promise<string> — lowercase hexadecimal SHA-256 digest (64 characters).
quickHashFile() uses fs.promises.open and positional reads (async I/O) rather than synchronous equivalents, so it does not block the Electron main process while reading large files.