跳到主要内容

分支管理

RxDB 提供类似 Git 的分支管理能力,让你可以在本地创建多个数据分支,安全地进行实验性修改,然后选择性地合并或切换分支。

快速开始​

分支与历史由 @aiao/rxdb-plugin-history 提供,不在 core 里:

pnpm add @aiao/rxdb-plugin-history
import { RxDB, SyncType } from '@aiao/rxdb';
import { rxDBPluginHistory } from '@aiao/rxdb-plugin-history';

const rxdb = new RxDB({
dbName: 'myApp',
entities: [Todo],
sync: { local: { adapter: 'wa-sqlite' }, type: SyncType.None }
});

rxdb.use(rxDBPluginHistory);
await rxdb.connect('wa-sqlite');

// 创建分支
await rxdb.versionManager.createBranch('feature-1');

// 切换分支
await rxdb.versionManager.switchBranch('feature-1');

// 删除分支
await rxdb.versionManager.removeBranch('feature-1');

:::warning versionManager 的可用时机 rxdb.versionManager 由历史插件在连接纪元内挂载,await connect() 之后才存在。没装插件时读它拿到的是 undefined——core 不做 fallback 兜底。

同步方法(syncRepository / bulkSync / push / pull 等)已经从 versionManager 搬到 @aiao/rxdb-plugin-sync 的 rxdb.syncManager,见历史与同步拆包。 :::

分支管理 API​

创建分支​

// 从当前状态创建分支
await rxdb.versionManager.createBranch('feature-1');

// 从指定 changeId 创建分支
await rxdb.versionManager.createBranch('feature-2', 12345);

切换分支​

await rxdb.versionManager.switchBranch('feature-1');
await rxdb.versionManager.switchBranch('main');

删除分支​

await rxdb.versionManager.removeBranch('feature-1');
注意

删除分支会同时删除该分支的所有变更历史。

获取当前分支​

import { RxDBBranch } from '@aiao/rxdb';

const currentBranch = await RxDBBranch.findOne({
where: {
combinator: 'and',
rules: [{ field: 'activated', operator: '=', value: true }]
}
});

使用场景​

测试新功能​

await rxdb.versionManager.createBranch('test-feature');
await rxdb.versionManager.switchBranch('test-feature');

const todo = new Todo();
todo.title = '测试任务';
await todo.save();

// 测试完成,切换回主分支
await rxdb.versionManager.switchBranch('main');
await rxdb.versionManager.removeBranch('test-feature');

离线编辑​

await rxdb.versionManager.createBranch('offline-work');
await rxdb.versionManager.switchBranch('offline-work');

// 离线修改...

// 恢复网络后切换回主分支
await rxdb.versionManager.switchBranch('main');

系统表结构​

系统表 RxDBChange 会通过数据库触发器(Trigger) 记录所有数据库的数据变化(插入,修改,删除),RxDBBranch 表会记录当前分支,这样我们就可以通过历史记录来计算出任何时刻的数据,再去修改其他表的数据达到切换版本的需求。

关键字段​

RxDBBranch

  • id: 分支标识符
  • fromChangeId: 分支起始点
  • activated: 是否为当前分支

RxDBChange

  • id: 变更序号(自增)
  • remoteId: 远程变更ID
  • branchId: 所属分支
  • type: insert | update | delete
  • patch: 正向变更(JSON Patch)
  • inversePatch: 逆向变更(用于回滚)
  • revertChangeId: 撤销时的变更ID
  • redoInvalidatedAt: redo 失效时间

分支合并​

把源分支的变更合并进当前激活分支(目标分支由当前激活分支决定,不作为参数传入):

// 压缩合并(默认):源分支全部变更压成目标分支上的一组事务记录
const result = await rxdb.versionManager.mergeBranch('feature-1');
console.log(`合并了 ${result.merged} 条变更,策略 ${result.strategy}`);

// 普通合并:逐条复制,保留历史细节
await rxdb.versionManager.mergeBranch('feature-1', { strategy: 'normal' });

// 合并后删除源分支
const merged = await rxdb.versionManager.mergeBranch('feature-1', { deleteSource: true });
if (!merged.sourceDeleted) console.warn('合并已落库,但删源分支没做成', merged.sourceDeleteError);

合并有变更时会清空 undo/redo 历史——合并本身不可逆。deleteSource 的删除是合并落库之后的收尾动作,失败不回滚合并、也不抛错,只在 sourceDeleted / sourceDeleteError 上如实报告。

相关文档​

  • 同步策略 - 了解数据同步配置
  • Undo/Redo - 撤销和重做功能
  • 工作树与提交历史 - 未提交改动捕获与提交历史(@aiao/rxdb-plugin-working-tree);装上该插件后 switchBranch() 多接受一个前置条件参数(requireClean / expectedActivationRevision),不传时行为与今天逐字节一致