Track Databases And Files
Graft repositories are worktree based. A commit can contain multiple SQLite database paths and ordinary files that belong to the same application state.
project/ data.sqlite analytics.sqlite settings.json attachments/ report.pdf .graft/Path Kinds
Section titled “Path Kinds”Graft reports what each path contains with kind:
| Kind | Meaning |
|---|---|
sqlite_database | SQLite database snapshot tracked through Graft. |
text_file | UTF-8 text file tracked as an app artifact. |
binary_file | Binary file tracked as an app artifact. |
Commands that accept --kind also accept common aliases such as sqlite,
db, text, and binary.
Storage Strategies
Section titled “Storage Strategies”storage describes how Graft stores the path:
| Storage | Used for |
|---|---|
sqlite_snapshot | SQLite database paths. |
inline | Small text files stored in the object database. |
external | Binary files, configured external paths, and large text files. |
Path kind and storage are separate. For example, a JSON file can be
kind: "text_file" and storage: "external" if it matches an external path
rule or exceeds the inline threshold.
Stage Everything
Section titled “Stage Everything”graft statusgraft add --allgraft commit -m "save app state"graft add --all stages database snapshots, file modifications, additions, and
deletions.
Filter by kind when an app wants to stage only one class of paths:
graft add --all --kind sqlite_databasegraft add --all --kind text_filegraft add --all --kind binary_fileStage one path:
graft add data.sqlitegraft add attachments/report.pdfIgnore Worktree Paths
Section titled “Ignore Worktree Paths”Graft reads .gitignore files from the repository root and descendant
directories by default. Rules use Git’s matching syntax and precedence,
including ! negation, / anchoring, directory-only patterns, **, ?,
character classes, comments, and escapes. As in Git, a file cannot be
re-included when one of its parent directories is excluded.
The Graft-specific .graftignore filename remains supported with the same
syntax. When both files exist in one directory, .graftignore rules take
precedence over .gitignore rules. Rules in deeper directories take precedence
over rules inherited from their parents.
Ignore rules affect untracked path discovery and ordinary adds; paths already
tracked by Graft continue to report and stage changes. Use
graft add --force path to add an ignored, untracked path intentionally.
Inspect Tracked And Untracked Paths
Section titled “Inspect Tracked And Untracked Paths”graft ls-filesgraft ls-files --jsongraft ls-files --json --detailsgraft ls-files --json --others--details includes object ids, content hashes, and whether external payloads
are present in the local cache. --others lists untracked worktree candidates
that can be added.
Configure File Storage
Section titled “Configure File Storage”Text files are stored inline until they exceed files.inline_text_threshold or
match files.external_paths.
graft config get files.inline_text_thresholdgraft config set files.inline_text_threshold 8 MBgraft config set files.external_paths "assets/**, attachments/**"Use external_paths for app resource directories such as attachments, imports,
exports, generated media, models, or assets.
Remove Paths
Section titled “Remove Paths”Stage a deletion:
graft rm attachments/report.pdfgraft commit -m "remove report"Remove a path from the repository while keeping the worktree file:
graft rm --cached attachments/report.pdfgraft commit -m "stop tracking report"External SQLite Edits
Section titled “External SQLite Edits”Normal SQLite tools are the default way to edit a physical worktree database. Commit the transaction, then stage the path:
sqlite3 data.sqlite "INSERT INTO notes(body) VALUES ('hello');"graft add data.sqlitegraft add captures committed WAL frames through SQLite’s online backup API;
manual checkpointing is unnecessary. It compares the consistent snapshot with
the staged or committed base and writes only changed 4 KiB Graft storage
chunks, independently of the physical database’s SQLite page size.