跳转到内容

合并冲突

Graft 先做 path-level merge。对 SQLite 数据库路径,它会比较 base、ours、 theirs snapshots,并尝试 row-aware merge。文件 artifact 默认使用保守的 file-level 处理。

Terminal window
graft switch main
graft --db data.sqlite merge feature/search

switch 会从当前目录发现并操作整个 repository;merge--db 打开 data.sqlite 做 row-aware analysis。干净合并后:

Terminal window
graft merge --continue -m "merge feature/search"

有冲突时:

Terminal window
graft status
graft conflicts
graft --db data.sqlite conflicts --json

这个例子从 app.sqlite 中的两个任务开始:

idtitlestatus
1Write quickstartopen
2Review commandsopen

创建仓库并提交初始状态:

Terminal window
mkdir app-state-demo
cd app-state-demo
graft init
graft sql --db app.sqlite \
"CREATE TABLE tasks(id INTEGER PRIMARY KEY, title TEXT, status TEXT); \
INSERT INTO tasks VALUES (1, 'Write quickstart', 'open'), \
(2, 'Review commands', 'open');"
graft add app.sqlite
graft commit -m "seed tasks"

feature branch 完成任务 1,并新增任务 3:

Terminal window
graft switch -c feature/progress
graft sql --db app.sqlite \
"UPDATE tasks SET status = 'done' WHERE id = 1; \
INSERT INTO tasks VALUES (3, 'Add screenshots', 'open');"
graft add app.sqlite
graft commit -m "record feature progress"

切回 main 会先 materialize 该分支的状态,然后再做另一组修改:

Terminal window
graft switch main
graft sql --db app.sqlite \
"UPDATE tasks SET status = 'blocked' WHERE id = 2; \
INSERT INTO tasks VALUES (4, 'Publish docs', 'open');"
graft add app.sqlite
graft commit -m "update docs status"

两个分支修改了不同的 rows:main 修改 rows 2、4,feature/progress 修改 rows 1、3。

Terminal window
graft --db app.sqlite merge feature/progress
graft conflicts
graft diff --rows --staged app.sqlite

graft conflicts 不会报告 unresolved paths。staged row diff 包含 feature branch 对 rows 1、3 的修改;main 已提交的 rows 2、4 保持不变。

Terminal window
graft merge --continue -m "merge feature progress"
graft sql --db app.sqlite \
"SELECT id, title, status FROM tasks ORDER BY id;"

合并后的数据库包含两个分支的结果:

idtitlestatus
1Write quickstartdone
2Review commandsblocked
3Add screenshotsopen
4Publish docsopen
  • 支持的 rowid table,以及按声明主键识别的 WITHOUT ROWID table 中的 disjoint row changes;包括 STRICT 和复合主键 schema
  • 兼容的 schema additions
  • 配置允许的 SQLite internal changes
  • 应用 merge plan 后通过 validation 的结果

不能证明安全时,Graft 会留下冲突。

Terminal window
graft --db data.sqlite resolve --ours data.sqlite
graft resolve --theirs attachments/report.pdf
graft resolve --manual settings.json

解决单个 SQLite row conflict:

Terminal window
graft --db data.sqlite resolve --theirs --row docs 42 data.sqlite
graft --db data.sqlite resolve --theirs --row docs '{"space_id":"space-1","id":"doc-1"}' data.sqlite

普通 rowid table 的 identity 是整数 rowid;WITHOUT ROWID table 则传包含全部 声明主键字段的 JSON object。

完成或中止:

Terminal window
graft merge --continue -m "resolve merge"
graft merge --abort

应用 UI 使用:

Terminal window
graft status --json
graft --db data.sqlite conflicts --json
graft --db data.sqlite resolve --json --theirs --row docs 42 data.sqlite

根据 kindstorage 渲染不同控件:SQLite 数据库显示 row/schema review, 文本文件显示 side picker 或编辑器,二进制/external 文件显示 ours/theirs/manual。