Usually, you will want to start a transaction before calling the procedure:
START TRANSACTION;
Merge can produce errors that need to be addressed before a transaction is committed. Opening a transaction allows these errors to be resolved by the client. If merge produces an error in AUTOCOMMIT mode, the transaction will be automatically rolled back and any merged tables will be reset.
The two errors that merge can produce are conflicts and constraint-violations. If either error exists post-merge, the conflicts column will be set to 1:
If no conflicts/constraint-violations were encountered, the current transaction will be completed, and a commit will be made. You can check the status of a merge using the dolt_merge_status system table:
If conflicts/constraint-violations were encountered, the current transaction will be left incomplete and you should resolve them using the instructions below. Once resolved, you will need to make a dolt commit.
Conflicts
Merging branches can create conflicts, which you must resolve before you can commit your transaction. If a merge creates conflicts, the DOLT_MERGE() function will return a non-zero result in the conflicts column.
Merges can generate conflicts on schema or data.
Schema
Merges with schema conflicts will prevent the merge from completing and populate schema conflicts rows into the dolt_schema_conflicts system table. This system table describes the conflicted table's schema on each side of the merge: ours and theirs. Additionally, it shows the table's schema at the common-ancestor and describes why the ours and theirs schemas cannot be automatically merged.
Merges that result in schema conflicts will leave an active merge state until the schema conflicts are resolved. Users can either --abort the active merge or resolve the schema conflict using dolt_conflicts_resolve(). dolt_conflicts_resolve() takes as arguments a table name and an option --ours or --theirs to specify which side of the merge should be accepted. It is important to note that this resolution strategy takes the entire table from the choosen side of the merge, not only its schema. Schema and data changes from the side of the merge not chosen are discarded with the resolution strategy. The schema and data changes still exist on the branch if you want to access them after the merge.
Data
Merges with data conflicts can be resolved using SQL. Conflicts must be resolved in the same SQL transaction by default. You can find which tables are in conflict by querying the dolt_conflicts system table:
SELECT*FROM dolt_conflicts;+--------+---------------+| table | num_conflicts |+--------+---------------+| people | 3 |+--------+---------------+
Each database table has an associated dolt_conflicts table, which you can SELECT, UPDATE and DELETE rows from to examine and resolve conflicts. For the hypothetical people table above, the conflict table looks like this:
For each column in the database table, the conflicts table has three columns: one for base, one for ours and one for theirs. These represent the three different values you might choose to resolve the conflict (either the common commit ancestor's values, the current table values, or the merged table values).
Resolving conflicts
To commit your transaction, you must first resolve the merge conflicts by deleting every row in every dolt_conflicts system table. This signals to Dolt that you have resolved every merge conflict to your satisfaction. There are several different strategies you could use, which you must repeat for every table in conflict.
Take ours
To use the values in the current working set (rather than the merged values), simply delete from the dolt_conflicts table without changing anything else.
DELETEFROM dolt_conflicts_people;
Take theirs
To use the merged values, overwriting our own, REPLACE and DELETE rows from the table using the conflicts table:
-- Replace existing rows with rows taken with their_* values as long-- as their_id is not null (rows deleted in theirs)REPLACEINTO people (id,first_name,last_name,age) (SELECT their_id, their_first_name, their_last_name, their_ageFROM dolt_conflicts_peopleWHERE their_id IS NOT NULL);-- Delete any rows that are deleted in theirsDELETEFROM PEOPLE WHERE id IN (SELECT base_idFROM dolt_conflictsWHERE base_id IS NOT NULLAND their_id ISNULL);-- mark conflicts resolvedDELETEFROM dolt_conflicts_people;
It's also possible to modify a table through the dolt_conflicts_$table_name table. If you update any column prefixed with our_, that will update the corresponding rows in the source table. This allows the REPLACE statement above to be re-written as:
UPDATE dolt_conflicts_peopleSET our_first_name = their_first_name, our_last_name = their_last_name, our_age = their_ageWHERE their_id IS NOT NULL;
It's also possible that you want your users to resolve conflicts themselves by picking which of the conflicting values to use for each row in conflict. You can build this workflow, or any other custom logic you want, with the SQL primitives above.
Committing with merge conflicts
By default, Dolt will not allow you to commit transactions that have merge conflicts, and will automatically rollback any transaction with merge conflicts when you attempt to COMMIT it. However, there may be times when you need to commit merge conflicts, for example to collaborate on resolving them with other people. To allow committing merge conflicts, change this system variable to 1 for every client that needs to commit merge conflicts:
If any table in your database contains foreign key constraints or unique key constraints, it's possible that a merge will create constraint violations. When this occurs, the conflicts column will be set to 1.
Let's walk through an example for foreign key constraints.
Foreign Key Constraint Violations
Imagine we have a parent table and a child table with this schema: