Skip to content

Merql

Pure PHP three-way database merge with column-level conflict resolution. Git-style merge semantics applied to MySQL and SQLite tables.

Terminal
composer require merql/merql

Latest release v0.4.1 MIT PHP 8.2+

In practice

A merge reads three saved snapshots and returns the operations to write and the conflicts to resolve.

Merge three snapshots

Take the base snapshot before the two copies diverge, then snapshot each side, for example a live database and a sandbox copy. ThreeWayMerge diffs both sides against the base and merges the two changesets.

In the result tab, ours edited content and theirs edited title and status of the same row, so the merge keeps all three edits without a conflict.

PHP
use Merql\Merge\ThreeWayMerge;

$merge = new ThreeWayMerge();
$result = $merge->merge($base, $ours, $theirs);

echo $result->operationCount(); // resolved operations
echo $result->conflictCount();  // unresolved conflicts

Three-Way Merge

Base, ours, theirs. A git-style three-way merge over keyed rows and columns instead of lines. Detects inserts, updates, and deletes across two branches.

Column-Level Resolution

When both sides change the same row, merql compares column by column. Only conflicts when the same column is changed to different values.

Opt-in Cell Merge

Pass a CellMergeConfig to ThreeWayMerge and TEXT columns merge line by line with Myers diff, JSON columns key by key. The Merql facade and the CLI do not enable it.

Multi-Database

Pluggable connection adapters and dialect drivers, with MySQL and SQLite built in.

Conflict Detection

Update vs update, update vs delete, delete vs update, and insert vs insert, each reported with table and row. Update vs update conflicts also name the column.

SQL Generation

Parameterized INSERT, UPDATE, DELETE statements with FK-aware ordering. Dry-run preview or apply in a transaction.

CLI

Snapshot, diff, and merge from the command line. Supports MySQL and SQLite via environment variables.

Tested

32 regression scenarios with hand-written expectations (composer test:oracle). CI runs 231 unit and integration tests and PHPStan level 10.

Why Merql

Snapshots are files

Each snapshot is one JSON file you can copy between machines or commit to version control. Diff and merge read those files, so they run without a database connection.

Review before you write

A merge plan gives every operation and change group a stable ID and keeps the base, ours, theirs and result rows. Select the groups you want and apply only those.

Stale plans stop

Guarded apply writes only to rows that still match the snapshot you reviewed. If a statement affects zero rows, the transaction rolls back and the result carries the error.

Rollback with a drift check

Build a rollback plan from the live rows just before the write and store it as JSON. Before undoing, the drift check compares row fingerprints and returns the operations whose rows have changed since.

Compared with

Merql merges row data from three snapshots. These tools version, sync or migrate databases, which are neighbouring jobs.

Merql compared with other tools
Dolt Good atDolt is a SQL database you can fork, clone, branch, merge, push and pull like a Git repository. You connect to it like any MySQL database, and it tracks the lineage of every cell. Difference with MerqlMerql keeps the MySQL or SQLite database you already run. It saves tables as JSON snapshot files and merges three of them, with the base snapshot chosen by you.
pt-table-sync Good atpt-table-sync finds and fixes differences between MySQL tables, one way or in both directions between servers. When it syncs a replica, it makes the changes on the replication source. Difference with MerqlIn a bidirectional sync, pt-table-sync picks a winning row by a conflict column and copies its values. Merql compares both sides with a common base, merges edits to different columns of the same row, and reports incompatible changes as conflicts for you to resolve.
sqldiff Good atsqldiff compares two SQLite databases and prints an SQL script that turns the first into the second. It can also write a binary changeset for the SQLite session extension or summarize changed rows per table. Difference with MerqlA two-way diff cannot tell whether one side added a row or the other deleted it. Merql adds a base snapshot to answer that, merges two sets of changes, and also works with MySQL.
Doctrine Migrations Good atDoctrine Migrations versions your database schema, so schema changes can be reviewed and tested before they are deployed to production. Difference with MerqlMerql is not a schema migration tool. It merges row data and reports columns added or removed between snapshots, leaving the schema change to you.

Questions and answers

Short answers from the Merql documentation.

Follow the guide from your first snapshot through merge plans, guarded apply and rollback.