Diffs
Graft has multiple diff layers because a SQLite database is a binary page store, while repository users want project-level history.
Repository Diff
Section titled “Repository Diff”Use repository diffs for day-to-day work:
graft diff HEAD~1 HEAD app.dbgraft diff --stagedgraft diff --json HEAD~1 HEAD app.dbgraft diff --rows HEAD~1 HEAD app.dbHuman output shows which database files changed and their snapshot size:
Diff 3e46006861d8..f0ac6701dc6cmodified: app.db from: 2 page(s), 1 range(s) to: 2 page(s), 1 range(s)JSON output includes the underlying snapshot descriptors:
graft diff --json HEAD~1 HEAD app.db | jqUse this when you need to inspect VolumeId, page count, log ranges, LSNs, or storage commit hashes.
Worktree And Staged Diff
Section titled “Worktree And Staged Diff”graft diffgraft diff HEADgraft diff HEAD -- app.dbgraft diff --stagedgraft diff --cached app.dbgraft diff main feature/search app.dbgraft diff HEAD~1 HEAD app.dbRow-Level Repository Diff
Section titled “Row-Level Repository Diff”Use --rows when you need to inspect table and row changes inside modified
SQLite database snapshots:
graft diff --rows HEAD~1 HEAD app.dbgraft diff --rows --staged app.dbgraft diff --json --rows HEAD~1 HEAD app.db--rows works with the same worktree, staged, and two-revision forms as the
default repository diff. Added and deleted database files remain file-level
changes because row diff needs both a before and after snapshot.
Example output:
Row Diff 3e46006861d8..f0ac6701dc6cmodified: app.db Diff LSN 2 -> 4 ============================
Table 'users': +1 inserts ~1 updates ~ rowid 1: old: [Null, Text("Alice")] new: [Null, Text("Alicia")] + rowid 2: [Null, Text("Bob")]JSON row diff:
graft diff --json --rows HEAD~1 HEAD app.db | jqJSON row diff includes logical_status, capabilities, and limitations.
These fields distinguish ordinary logical changes from unsupported SQLite
surfaces and file-only changes with no supported row/schema delta. See
Merge Policy for the
status values.
Storage LSN Debug Diff
Section titled “Storage LSN Debug Diff”Debug row-level diff can still compare raw storage LSNs directly. This is most useful when debugging the storage layer rather than normal repository history.
First get storage log positions:
graft sql "PRAGMA graft_debug_log_lsn;"Then compare two LSNs:
graft sql "PRAGMA graft_debug_volume_diff = '2,4,rows';"Example output:
Row-level diff from LSN 2 to LSN 4
Changed tables: 1
Table: users Changes: 2 +1 inserts ~1 updates [1] UPDATE rowid=1 old: "Null, Text(\"Alice\")" new: "Null, Text(\"Alicia\")" [2] INSERT rowid=2 values: "Null, Text(\"Bob\")"JSON row diff:
graft sql "PRAGMA graft_debug_volume_json_diff = '2,4,rows';" | jqWhy The Layers Are Separate
Section titled “Why The Layers Are Separate”Repository diffs answer:
Which project files changed between two repository states?
Snapshot diffs answer:
Which database snapshots, page counts, and storage ranges differ?
Row-level repository diffs answer:
Which tables and rowids appear to have changed when interpreting the SQLite pages?
All three are useful. They should not be collapsed into one mental model.