Dolt 版本化 SQL 实战

Dolt v2.5.0 版本化 SQL 全量实战:CLI 与存储过程双形态的分支/暂存/提交/合并、行级冲突解决两条路径、AS OF 时间旅行、dolt_diff/dolt_history/dolt_log 表函数、blame 追溯与版本化函数速查,全部建库实测。

DoltDolt2026/10/18

Dolt 版本化 SQL 实战

‍‍​​‌​> 目标:把 Dolt 区别于一切传统数据库的「版本化能力」做扎实——分支/合并/冲突解决/时间旅行/行级追溯在 CLI 与 SQL 存储过程两种形态下的完整用法;全部语句与回显均在 Ubuntu 22.04 LTS + Dolt v2.5.0 真实建库(/opt/data/dolt/demo,products 表)逐条实测,安装与基础闭环见《Dolt 安装部署指南》《Dolt 快速入门》。

一、环境信息

本文所有命令与回显所依赖的实测环境:

  • 操作系统:Ubuntu 22.04 LTS(x86_64)
  • Dolt:v2.5.0(dolt version 实测 2.5.0)
  • 实验仓库:/opt/data/dolt/demo(含 products 表,初始 3 行数据:1-Keyboard、2-Mouse、3-Monitor)
  • 全局配置:user.name=admin、user.email=admin@quzuo.net
  • 本文提交哈希均为内容寻址生成(base32 长串),读者复现时哈希值必然不同,以自己环境输出为准

二、前置条件

cd /opt/data/dolt/demo
dolt version
dolt sql -q "select * from products"

实测回显:

dolt version 2.5.0

+----+----------+---------+-------+
| id | name     | price   | stock |
+----+----------+---------+-------+
| 1  | Keyboard | 199.00  | 50    |
| 2  | Mouse    | 89.50   | 120   |
| 3  | Monitor  | 1299.00 | 20    |
+----+----------+---------+-------+

💡 说明:若仓库数据与上文不一致,只需保证有一张带主键的表即可——Dolt 的合并冲突以主键为对齐依据,无主键表无法做行级合并。

三、版本化体系总览

Dolt 的版本化操作有三套等价形态,可以混用(实测互通):

形态入口代表操作适用场景
CLI 命令dolt branch/checkout/...Git 同名命令,语义一致本地手工操作、脚本
SQL 存储过程CALL DOLT_BRANCH(...)在 SQL 会话里完成版本操作通过 MySQL 协议远程操作(见《Dolt 集成实战》)、应用内嵌版本逻辑
系统表dolt_log、dolt_conflicts、dolt_history_<表>只读查询版本元数据报表、审计、程序化读取历史

三条铁律贯穿全文:

  1. 提交引用:main、main~1、提交哈希、分支名、tag 名均可用作版本引用;
  2. add-commit 模型:工作区 → dolt add 暂存 → dolt commit 提交,与 Git 相同;
  3. 存储过程返回结构化结果:CALL 的回显是结果集(status/hash 等),可直接被程序消费。

四、分支与工作区管理

本节建立两个平行视角:CLI 与存储过程执行同一组分支操作。

4.1 CLI:创建、切换、删除分支

dolt checkout -b price-adjust
dolt branch
dolt sql -q "update products set price = price * 0.8 where id in (1,2)"
dolt add products
dolt commit -m "促销:Keyboard 与 Mouse 打八折"
dolt checkout main
dolt sql -q "select id, price from products where id = 1"

实测回显:

Switched to branch 'price-adjust'
  main
* price-adjust

+----+----------+---------+
| id | name     | price   |
+----+----------+---------+
| 1  | Keyboard | 159.20  |
| 2  | Mouse    | 71.60   |
| 3  | Monitor  | 1299.00 |
+----+----------+---------+

Switched to branch 'main'

+----+---------+
| id | price   |
+----+---------+
| 1  | 199.00  |
+----+---------+

主干上 id=1 仍是 199.00,分支修改互不可见。删除已合并分支用 dolt branch -d <名>,强制删除用 -D(实测未合并分支 -d 会拒绝:branch 'abort-a' is not fully merged. If you are sure you want to delete it, run 'dolt branch -D abort-a')。

4.2 存储过程:同一闭环的 SQL 形态

dolt sql -q 'call dolt_branch("sql-proc-branch"); call dolt_checkout("sql-proc-branch"); insert into products values (4, "Webcam", 259.00, 15); call dolt_add("-A"); call dolt_commit("-m", "SQL 存储过程新增 Webcam 产品"); call dolt_checkout("main"); call dolt_merge("sql-proc-branch"); select id, name from products'

实测回显(逐段对应每条语句的结果集):

+--------+
| status |
+--------+
| 0      |
+--------+

+--------+--------------------------------------+
| status | message                              |
+--------+--------------------------------------+
| 0      | Switched to branch 'sql-proc-branch' |
+--------+--------------------------------------+

+--------+
| status |
+--------+
| 0      |
+--------+

+----------------------------------+
| hash                             |
+----------------------------------+
| bnr6hn83fvlk01pcl8ojc6vaui11r210 |
+----------------------------------+

+--------+---------------------------+
| status | message                   |
+--------+---------------------------+
| 0      | Switched to branch 'main' |
+--------+---------------------------+

+----------------------------------+--------------+-----------+------------------+
| hash                             | fast_forward | conflicts | message          |
+----------------------------------+--------------+-----------+------------------+
| bnr6hn83fvlk01pcl8ojc6vaui11r210 | 1            | 0         | merge successful |
+----------------------------------+--------------+-----------+------------------+

+----+----------+
| id | name     |
+----+----------+
| 1  | Keyboard |
| 2  | Mouse    |
| 3  | Monitor  |
| 4  | Webcam   |
+----+----------+

逐个结果集解读:

  • dolt_branch/dolt_add:返回单列 status(0=成功);
  • dolt_checkout:返回 status + message(与 CLI 同文案);
  • dolt_commit:返回新提交的 hash;
  • dolt_merge:返回 hash、fast_forward(1=快进合并)、conflicts(冲突数)、message——这四个字段是程序判断合并结果的标准依据。

五、暂存与提交

5.1 暂存、提交与回滚

dolt add 暂存指定表(-A 暂存全部),dolt commit 落提交;未提交的修改用 dolt reset 撤销:

dolt sql -q "update products set stock = 99 where id = 2"
dolt status
dolt reset --hard
dolt sql -q "select stock from products where id = 2"

实测回显:

On branch main

Changes not staged for commit:
  (use "dolt add <table>" to update what will be committed)
  (use "dolt checkout <table>" to discard changes in working directory)
        modified:         products

+-------+
| stock |
+-------+
| 120   |
+-------+

存储过程等价形态:call dolt_reset()(仅撤销暂存)与 call dolt_reset("--hard")(连工作区一起回滚),实测均返回 status 0。

5.2 打标签 tag

dolt sql -q 'call dolt_tag("v1.0", "HEAD")'
dolt sql -q 'select tag_name, tag_hash, tagger, message from dolt_tags'
dolt tag -v

实测回显:

+--------+
| status |
+--------+
| 0      |
+--------+

+----------+----------------------------------+--------+---------+
| tag_name | tag_hash                         | tagger | message |
+----------+----------------------------------+--------+---------+
| v1.0     | bnr6hn83fvlk01pcl8ojc6vaui11r210 | admin  |         |
+----------+----------------------------------+--------+---------+

v1.0    bnr6hn83fvlk01pcl8ojc6vaui11r210
Tagger: admin <admin@quzuo.net>
Date:   Sun Oct 18 11:13:45 +0800 2026

⚠️ 版本差异(v2.5.0 实测):dolt_tag 的签名是 DOLT_TAG(tag名, 起始引用) 两参数——带 message 的三参数形式会报 create tag takes at most two args;无参的 DOLT_TAG() 列举标签也不被支持(报 use 'dolt_tags' system table to list tags),列举一律查 dolt_tags 系统表。给 tag 写说明可用 CLI:dolt tag v1.0 -m "说明"。

5.3 摘取提交 cherry-pick

把另一分支上的单个提交摘到当前分支:

dolt sql -q 'call dolt_cherry_pick("sql-proc-branch")'
dolt log -n 1

实测回显:

+----------------------------------+----------------+------------------+-----------------------+
| hash                             | data_conflicts | schema_conflicts | constraint_violations |
+----------------------------------+----------------+------------------+-----------------------+
| 1ugn4905ib2cm9qog29hllfi79t114m3 | 0              | 0                | 0                     |
+----------------------------------+----------------+------------------+-----------------------+

commit 1ugn4905ib2cm9qog29hllfi79t114m3
Author: admin <admin@quzuo.net>
Date:  Sun Oct 18 11:14:11 +0800 2026

        分支上新增 USB Hub

返回结构里的 data_conflicts/schema_conflicts/constraint_violations 三列全 0 表示干净摘取。若摘取的改动在目标分支已存在,会报 no changes were made, nothing to commit(实测)。

六、合并与冲突解决

6.1 制造一次行级冲突

两个分支各自修改同一行(id=1 的 price),合并时无法自动抉择:

dolt checkout -b feature-a
dolt sql -q "update products set price = 259.00 where id = 1"
dolt add products && dolt commit -m "feature-a: 调整 Keyboard 至 259.00"
dolt checkout main && dolt checkout -b feature-b
dolt sql -q "update products set price = 288.00 where id = 1"
dolt add products && dolt commit -m "feature-b: 调整 Keyboard 至 288.00"
dolt checkout feature-a
dolt merge feature-b

实测回显(最后一步):

Switched to branch 'feature-a'
Switched to branch 'main'
Switched to branch 'feature-b'
Switched to branch 'feature-a'
Auto-merging products
CONFLICT (content): Merge conflict in products
Automatic merge failed; 1 table(s) are unmerged.
Use 'dolt conflicts' to investigate and resolve conflicts.

💡 说明:Dolt 的合并是以主键对齐的三方合并——共同祖先(merge-base)为 base,两侧分支为 ours/theirs;主键相同且同列被双方改掉的行进入冲突集。无冲突时合并自动生成 merge 提交,有冲突时合并停在「进行中」状态(这就是 --abort 的作用窗口)。

6.2 CLI 查看冲突:dolt conflicts cat

dolt conflicts cat products
dolt sql -q "select * from products"

实测回显:

+-----+--------+----+----------+--------+-------+------+------+-------+-------+------+------+-------+-------+
|     |        | id | name     | price  | stock | id   | name | price | stock | id   | name | price | stock |
+-----+--------+----+----------+--------+-------+------+------+-------+-------+------+------+-------+-------+
|     | base   | 1  | Keyboard | 159.20 | 50    | NULL | NULL | NULL  | NULL  | NULL | NULL | NULL  | NULL  |
|  *  | ours   | 1  | Keyboard | 259.00 | 50    | NULL | NULL | NULL  | NULL  | NULL | NULL | NULL  | NULL  |
|  *  | theirs | 1  | Keyboard | 288.00 | 50    | NULL | NULL | NULL  | NULL  | NULL | NULL | NULL  | NULL  |
+-----+--------+----+----------+--------+-------+------+------+-------+-------+------+------+-------+-------+

+----+----------+---------+-------+
| id | name     | price   | stock |
+----+----------+---------+-------+
| 1  | Keyboard | 259.00  | 50    |
| 2  | Mouse    | 71.60   | 120   |
| 3  | Monitor  | 1299.00 | 20    |
+----+----------+---------+-------+

三行分别给出 base(共同祖先)/ours(当前分支)/theirs(被合并方)三个版本;冲突未解决前,普通查询显示的是 ours 值(259.00)。

6.3 路径一:CLI 一键解决(--ours / --theirs)

dolt conflicts resolve products --theirs
dolt sql -q "select id, price from products where id = 1"
dolt add products
dolt commit -m "merge feature-b:采纳 theirs 版本 Keyboard 288.00"
dolt log -n 1

实测回显:

+----+---------+
| id | price   |
+----+---------+
| 1  | 288.00  |
+----+---------+

commit uh0sq215ehg591be7ln9qa5jut9pcggk (HEAD -> feature-a)
Merge: kntitf5lvkikcdktash23qej9lpnmlfj 1ndo2t0nh1t8vf15bum2oeu6ml3jp605
Author: admin <admin@quzuo.net>
Date:  Sun Oct 18 11:11:23 +0800 2026

        merge feature-b:采纳 theirs 版本 Keyboard 288.00

--theirs 采纳对方值(288.00);--ours 保留自己值;解决后必须 dolt add + dolt commit 才能完结合并。

6.4 路径二:SQL 手工解决(autocommit 必须关闭)

先看冲突系统表结构:

dolt sql -q 'describe dolt_conflicts_products'

实测回显(关键列节选):

+------------------+---------------+------+-----+---------+-------+
| Field            | Type          | Null | Key | Default | Extra |
+------------------+---------------+------+-----+---------+-------+
| base_id          | int           | YES  |     | NULL    |       |
| base_price       | decimal(10,2) | YES  |     | NULL    |       |
| our_id           | int           | NO   |     | NULL    |       |
| our_price        | decimal(10,2) | YES  |     | NULL    |       |
| their_id         | int           | YES  |     | NULL    |       |
| their_price      | decimal(10,2) | YES  |     | NULL    |       |
| dolt_conflict_id | varchar(1023) | YES  |     | NULL    |       |
+------------------+---------------+------+-----+---------+-------+

业务列以 base_/our_/their_ 前缀平铺在一张宽表里。冲突总数则查 dolt_conflicts:

dolt sql -q 'select * from dolt_conflicts'

实测回显:

+----------+---------------+
| table    | num_conflicts |
+----------+---------------+
| products | 1             |
+----------+---------------+

手工解决的标准流程(先造一次新冲突:feature-c 分支改 id=3 的 stock 为 30,main 改为 18,合并冲突):

dolt sql -q 'set autocommit=0; select num_conflicts from dolt_conflicts where `table`="products"; update products set stock = 25 where id = 3; call dolt_conflicts_resolve("products", "--theirs"); commit; select id, name, price, stock from products'

实测回显:

+---------------+
| num_conflicts |
+---------------+
| 1             |
+---------------+

+----+----------+---------+-------+
| id | name     | price   | stock |
+----+----------+---------+-------+
| 1  | Keyboard | 288.00  | 50    |
| 2  | Mouse    | 71.60   | 120   |
| 3  | Monitor  | 1299.00 | 30    |
+----+----------+---------+-------+

⚠️ 两个实测出的关键细节:

  1. 冲突态下写工作区必须先 set autocommit=0:否则报 Merge conflict detected, @autocommit transaction rolled back. @autocommit must be disabled so that merge conflicts can be resolved using the dolt_conflicts and dolt_schema_conflicts tables before manually committing the transaction. Alternatively, to commit transactions with merge conflicts, set @@dolt_allow_commit_conflicts = 1——报错本身已给出两条出路,非常明确。
  2. DOLT_CONFLICTS_RESOLVE(表, "--ours"/"--theirs") 会用对应版本整体覆盖工作区:上例先手工 update stock=25 再 --theirs,最终 stock 是 theirs 的 30 而不是 25。想「取双方混合值」的正确姿势:关闭 autocommit → 手工改工作区到目标值 → 再执行 call dolt_conflicts_resolve("products") 仅清除冲突标记(或直接 dolt conflicts resolve products)→ commit。
  3. 存储过程的参数是带连字符的标志串 "--theirs",写 "theirs" 会报 --ours or --theirs must be supplied(实测)。

手工流程收尾(把手工值提交为 merge commit):

dolt add products
dolt commit -m "merge feature-c:冲突经手工 SQL 解决"
dolt status

实测回显:

On branch main
nothing to commit, working tree clean

6.5 中止合并:dolt merge --abort

冲突想整体放弃、回到合并前状态:

dolt checkout -b abort-a
dolt sql -q "update products set stock = 444 where id = 2"
dolt add products && dolt commit -m "abort-a: stock 444"
dolt checkout main && dolt checkout -b abort-b
dolt sql -q "update products set stock = 555 where id = 2"
dolt add products && dolt commit -m "abort-b: stock 555"
dolt checkout abort-a
dolt merge abort-b
dolt merge --abort
dolt status
dolt sql -q 'select id, stock from products where id = 2'

实测回显(关键两步):

Auto-merging products
CONFLICT (content): Merge conflict in products
Automatic merge failed; 1 table(s) are unmerged.
Use 'dolt conflicts' to investigate and resolve conflicts.

fatal: There is no merge to abort

实测要点:--abort 只在「合并进行中」有效。本次实测中合并因冲突中断、处于进行中,dolt merge --abort 执行后:

On branch abort-a
nothing to commit, working tree clean

+----+-------+
| id | stock |
+----+-------+
| 2  | 444   |
+----+-------+

工作区干净、id=2 恢复为 abort-a 的 444,完全回到合并前。若合并已经成功提交(无冲突自动提交的场景)再跑 --abort,会报 fatal: There is no merge to abort(实测),此时回退要靠 dolt revert 或 dolt reset --hard。

6.6 约束校验:dolt_verify_constraints

冲突解决(尤其手工改值)后,检查外键/约束是否被违反:

dolt sql -q 'call dolt_verify_constraints()'

实测回显(空结果集 = 无违反):

+------------+
| violations |
+------------+

七、历史与时间旅行

7.1 提交历史:dolt log 与 dolt_log 表函数

CLI 形态与表函数形态二选一,表函数可在 SQL 里过滤:

dolt sql -q 'select commit_hash, committer, message from dolt_log limit 3'

实测回显:

+----------------------------------+-----------+---------------------------------------------------------------+
| commit_hash                      | committer | message                                                       |
+----------------------------------+-----------+---------------------------------------------------------------+
| 5fr6kuq8kag87g9j9hrcbvmgihm8h4tp | admin     | merge feature-c:冲突经 dolt_conflicts_resolve(--theirs) 解决 |
| fl27nl6eu0d19f44mo3308el0e40jjcr | admin     | feature-c: Monitor 库存 30                                    |
| uh0sq215ehg591be7ln9qa5jut9pcggk | admin     | merge feature-b:采纳 theirs 版本 Keyboard 288.00             |
+----------------------------------+-----------+---------------------------------------------------------------+

CLI 的 dolt log -n 3 输出包含 Author/Date 的完整格式;dolt log --oneline -n 3 为单行格式(实测均支持)。

7.2 AS OF 时间旅行查询

AS OF <引用> 后缀让任何表在「任意历史时刻」可查,引用可以是提交哈希、分支名,甚至 main~1:

dolt sql -q 'select id, name, price, stock from products as of "53lb9ufgdfk6m60dob20n13imvpsqbpo"'
dolt sql -q 'select id, price from products as of "main~1" where id = 1'

实测回显:

+----+----------+---------+-------+
| id | name     | price   | stock |
+----+----------+---------+-------+
| 1  | Keyboard | 199.00  | 50    |
| 2  | Mouse    | 89.50   | 120   |
| 3  | Monitor  | 1299.00 | 20    |
+----+----------+---------+-------+

+----+---------+
| id | price   |
+----+---------+
| 1  | 288.00  |
+----+---------+

第一段是仓库首个提交时刻的完整快照(Keyboard 还是 199.00);第二段取 main 的上一次提交。开销实测:在千行级小表上 AS OF 与普通查询耗时几乎相同(实测 real 0m0.039s vs 0m0.041s),因为历史版本本身就是内容寻址存储里的另一棵树,不需要回放日志重建。

7.3 行级历史:dolt_history_<表>

每个表自动挂一个 dolt_history_<表名> 系统表,返回每一行在每个提交里的样子:

dolt sql -q 'select id, price, commit_hash, committer, commit_date from dolt_history_products where id = 1 order by commit_date limit 4'

实测回显:

+----+--------+----------------------------------+-----------+-------------------------+
| id | price  | commit_hash                      | committer | commit_date             |
+----+--------+----------------------------------+-----------+-------------------------+
| 1  | 199.00 | 53lb9ufgdfk6m60dob20n13imvpsqbpo | admin     | 2026-10-18 03:10:27.465 |
| 1  | 159.20 | o93jcrjiirvurhsd92dtsi9cv5kfoctl | admin     | 2026-10-18 03:10:38.035 |
| 1  | 259.00 | kntitf5lvkikcdktash23qej9lpnmlfj | admin     | 2026-10-18 03:10:58.460 |
| 1  | 288.00 | 1ndo2t0nh1t8vf15bum2oeu6ml3jp605 | admin     | 2026-10-18 03:10:58.714 |
+----+--------+----------------------------------+-----------+-------------------------+

💡 说明:id=1 的价格变迁史一目了然(199→159.20→259→288)。注意 commit_date 为 UTC 时间(03:10 对应本地 11:10,时区 +08:00)。v2.5.0 实测该系统表没有 commit_message 列(只有 commit_hash/committer/commit_date),要带消息需自行 join dolt_log。

7.4 行级追溯:dolt blame

「每行最后一次修改发生在哪个提交」:

dolt blame products

实测回显(节选):

+----+----------------------------------+----------------------------+-----------+-----------------+---------------------------------------------------------------+
| id | commit                           | commit_date                | committer | email           | message                                                       |
+----+----------------------------------+----------------------------+-----------+-----------------+---------------------------------------------------------------+
| 1  | 5fr6kuq8kag87g9j9hrcbvmgihm8h4tp | 2026-10-18 03:12:31.993000 | admin     | admin@quzuo.net | merge feature-c:冲突经 dolt_conflicts_resolve(--theirs) 解决 |
| 2  | o93jcrjiirvurhsd92dtsi9cv5kfoctl | 2026-10-18 03:10:38.035000 | admin     | admin@quzuo.net | 促销:Keyboard 与 Mouse 打八折                                |
| 3  | 5fr6kuq8kag87g9j9hrcbvmgihm8h4tp | 2026-10-18 03:12:31.993000 | admin     | admin@quzuo.net | merge feature-c:冲突经 dolt_conflicts_resolve(--theirs) 解决 |
+----+----------------------------------+----------------------------+-----------+-----------------+---------------------------------------------------------------+

与 dolt_history_ 的区别:history 给「每行的全部历史版本」,blame 只给「当前每行的最后修改者」——对标代码的 git blame。

7.5 提交间差异:dolt_diff 表函数

dolt sql -q 'select to_price, from_price, to_commit, from_commit from dolt_diff("main~1", "main", "products") where to_id=1'

实测回显:

+----------+------------+-----------+-------------+
| to_price | from_price | to_commit | from_commit |
+----------+------------+-----------+-------------+
| 288.00   | 159.20     | main      | main~1      |
+----------+------------+-----------+-------------+

三参数为「起始引用、目标引用、表名」,返回列名以 from_/to_ 前缀区分两个版本的值;where to_id=1 即按主键过滤。CLI 等价形态是 dolt diff main~1 main。

八、版本化函数与存储过程速查(v2.5.0 实测)

名称类型作用本文实测节
DOLT_BRANCH(名) / DOLT_BRANCH()存储过程建分支 / 列分支4.2
DOLT_CHECKOUT(分支)存储过程切换分支4.2
DOLT_ADD("-A")存储过程暂存全部变更4.2
DOLT_COMMIT("-m", 消息)存储过程提交,返回 hash4.2
DOLT_MERGE(分支)存储过程合并,返回 hash/fast_forward/conflicts4.2
DOLT_RESET() / DOLT_RESET("--hard")存储过程撤销暂存 / 连工作区回滚5.1
DOLT_TAG(名, 引用)存储过程打 tag(v2.5.0 仅两参数)5.2
DOLT_CHERRY_PICK(引用)存储过程摘取单个提交5.3
DOLT_CONFLICTS_RESOLVE(表, "--ours"/"--theirs")存储过程冲突解决6.4
DOLT_VERIFY_CONSTRAINTS()存储过程校验外键/约束6.6
DOLT_GC()存储过程垃圾回收无引用数据块—(实测返回 status 0)
dolt_log / dolt_diff / dolt_history_<表> / dolt_tags / dolt_conflicts表函数/系统表历史与冲突元数据5.2、6.4、7.x

⚠️ v2.5.0 版本差异实测:dolt_show_artifacts 存储过程已不存在(报 stored procedure "dolt_show_artifacts" does not exist);无参 DOLT_TAG() 列举标签同样不支持,一律改查 dolt_tags 系统表。老教程里的这两个用法在本版本会直接报错。

九、场景化模式:分支试运行 → 验证 → 合并

把前文能力串成生产里最常见的「数据变更试运行」流程(本节命令均实测自同一环境):

dolt checkout -b pricing-experiment
dolt sql -q "update products set price = round(price * 1.1, 2)"
dolt add products && dolt commit -m "提价 10% 试验"
dolt diff main pricing-experiment

实测回显(id=4~7 为本文 4.2、5.3、6.5 节实验陆续追加的产品行):

+---+----+-------------+---------+-------+
|   | id | name        | price   | stock |
+---+----+-------------+---------+-------+
| < | 1  | Keyboard    | 288.00  | 50    |
| > | 1  | Keyboard    | 316.80  | 50    |
| < | 2  | Mouse       | 71.60   | 120   |
| > | 2  | Mouse       | 78.76   | 120   |
| < | 3  | Monitor     | 1299.00 | 30    |
| > | 3  | Monitor     | 1428.90 | 30    |
| < | 4  | Webcam      | 259.00  | 15    |
| > | 4  | Webcam      | 284.90  | 15    |
| < | 5  | USB Hub     | 79.00   | 40    |
| > | 5  | USB Hub     | 86.90   | 40    |
| < | 6  | HDMI Cable  | 29.90   | 200   |
| > | 6  | HDMI Cable  | 32.89   | 200   |
| < | 7  | Power Strip | 59.90   | 80    |
| > | 7  | Power Strip | 65.89   | 80    |
+---+----+-------------+---------+-------+

验证无误后合并生效;发现方案不可行则 dolt branch -D pricing-experiment 直接丢弃分支——主干自始至终未受影响。这套「改在分支、看 diff、再合并」的流程就是 Dolt 相对传统数据库的核心价值。

十、常见问题

Q1:冲突态下直接 delete from products ... 报 Merge conflict detected, @autocommit transaction rolled back? 先 set autocommit=0 再操作,流程见 6.4 节;或临时 set @@dolt_allow_commit_conflicts = 1 允许带冲突提交(不建议,冲突会滞留在系统表)。

Q2:DOLT_TAG("v1.0", "HEAD", "说明") 报 create tag takes at most two args? v2.5.0 的 SQL 存储过程签名只收两个参数;需要 tag 说明用 CLI:dolt tag v1.0 -m "说明"。

Q3:AS OF 查老版本报引用不存在? 被引用的提交必须还在提交图上(未被 dolt gc 清理)。清理前的引用都有效;dolt reflog 可查最近引用历史(实测 dolt reflog 子命令存在)。

Q4:合并后想撤销整个 merge commit? 未提交时 dolt merge --abort(见 6.5);已提交时用 dolt revert <merge哈希> 生成反向提交(保留历史,适合共享分支),或私有分支上 dolt reset --hard main~1(改写历史)。

Q5:dolt_conflicts_<表> 宽表的列名怎么确定? describe dolt_conflicts_<表名>(见 6.4 实测),业务列带 base_/our_/their_ 三组前缀,另有 dolt_conflict_id 标识冲突组。

十一、参考链接