Skip to content

Diffs

Graft has multiple diff layers because a SQLite database is a binary page store, while repository users want project-level history.

Use repository diffs for day-to-day work:

Terminal window
graft diff HEAD~1 HEAD app.db
graft diff --staged
graft diff --json HEAD~1 HEAD app.db
graft diff --rows HEAD~1 HEAD app.db

Human output shows which database files changed and their snapshot size:

Diff 3e46006861d8..f0ac6701dc6c
modified: app.db
from: 2 page(s), 1 range(s)
to: 2 page(s), 1 range(s)

JSON output includes the underlying snapshot descriptors:

Terminal window
graft diff --json HEAD~1 HEAD app.db | jq

Use this when you need to inspect VolumeId, page count, log ranges, LSNs, or storage commit hashes.

Terminal window
graft diff
graft diff HEAD
graft diff HEAD -- app.db

Use --rows when you need to inspect table and row changes inside modified SQLite database snapshots:

Terminal window
graft diff --rows HEAD~1 HEAD app.db
graft diff --rows --staged app.db
graft 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..f0ac6701dc6c
modified: 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:

Terminal window
graft diff --json --rows HEAD~1 HEAD app.db | jq

JSON 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.

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:

Terminal window
graft sql "PRAGMA graft_debug_log_lsn;"

Then compare two LSNs:

Terminal window
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:

Terminal window
graft sql "PRAGMA graft_debug_volume_json_diff = '2,4,rows';" | jq

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.