-
Notifications
You must be signed in to change notification settings - Fork 35
Merging branches
- Merge
- Rebase
- Forward Merge
- With conflict detection (default, slower)
- Without conflict detection (using
--force
)
Due to its nature, there are no conflicts on a forward merge. So no conflict detection is used.
PRAGMA branch_merge [--check|--force] {source} [{dest}]
PRAGMA branch_rebase [--check|--force] [{to_rebase}] {new_base} [{new_branch}]
Where to_rebase
can be:
- a branch name
- a single commit, like
branch.commit
- a commit range, like
branch.start-end
If to_rebase
is omitted then it rebases the current branch.
When rebasing a single commit or a range of commits to an internal commit we must supply the name for the new_branch
that will be created.
We can also rebase them to the end of a branch. In this case if no new_branch
name is supplied, the commit(s) will be rebased onto the destination branch.
PRAGMA branch_merge --forward {parent} {child} [{num_commits}]
PRAGMA branch_merge --forward {parent} {child.commit}
Merging the test branch into the master branch:
PRAGMA branch=master
PRAGMA branch_merge test
Merging the test branch up to commit 25 into the master branch:
PRAGMA branch=master
PRAGMA branch_merge test.25
Rebasing the test branch onto the end of the master branch:
PRAGMA branch=test
PRAGMA branch_rebase master
Rebasing the test branch onto commit 20 of the master branch:
PRAGMA branch=test
PRAGMA branch_rebase master.20
Moving the commits 25 thru 27 from the master branch to the dev branch:
PRAGMA branch_rebase master.25-27 dev
Moving the commits 25 thru 27 from the master branch to a new branch named test that will start at the dev branch:
PRAGMA branch_rebase master.25-27 dev test
Moving the commits 25 thru 27 from the master branch to a new branch named test that will start at the master branch's commit 20:
PRAGMA branch_rebase master.25-27 master.20 test
Advancing the master branch 3 commits in the direction of the test branch:
PRAGMA branch_merge --forward master test 3
Advancing the master branch in the direction of the test branch up to commit 25:
PRAGMA branch_merge --forward master test.25
Advancing the master branch in the direction of the test branch all the way up to (and including) the last commit:
PRAGMA branch_merge --forward master test
LiteTree performs will perform conflict detection by default on merge and rebase operations.
If you want to omit it, use the --force
parameter, like this:
PRAGMA branch=master
PRAGMA branch_merge --force test
PRAGMA branch=test
PRAGMA branch_rebase --force master
If you want to perform just a conflict detection you can use the --check
parameter on both merge and rebase operations. eg:
PRAGMA branch=master
PRAGMA branch_merge --check test
PRAGMA branch=test
PRAGMA branch_rebase --check master
On these cases no merge or rebase is performed.
LiteTree will not implement conflict resolution. The conflicts must be resolved manually, either by:
- Choosing another point for merge or rebase
- Editing existing commits
- Adding or removing commits
Use the stored SQL commands from the source branch and run them in the destination branch.
Problem: if a previous merge was already done (from previous or the same commit)
Solution 1: use the SQL commands starting at the last merge
This implies storing merge info/history.
- Easy to implement
- No conflict detection
- Merging can take a long time to be processed if the SQL commands are complex (because they are re-executed)
Store a modified SQL command on each execution, in which do not depends on previous values.
eg:
UPDATE t1 SET count = count + 1 WHERE id=3
becomes:
UPDATE t1 SET count = 10 WHERE id=3
if count
was previously 9
.
UPDATE t1 SET count = count + 1
becomes:
UPDATE t1 SET count = 15 WHERE id=1
UPDATE t1 SET count = 12 WHERE id=2
UPDATE t1 SET count = 10 WHERE id=3
...
And
UPDATE t1 SET col1 = col2 WHERE col3 > 10
becomes:
UPDATE t1 SET col1 = "John" WHERE id=11
UPDATE t1 SET col1 = "Mary" WHERE id=17
UPDATE t1 SET col1 = NULL WHERE id=19
...
Note: using the session / changeset feature is better suited to execute these commands because we don't need to parse each of them.
Note 2: maybe in some cases the user wants that a command like UPDATE products SET active = 1
affect all the rows, even the ones included from the merging process. So it could have an option to use the plain/original command (affecting all rows) or affect just the ones from that commit.
Compare all the rows from source and destination branches.
Detect duplicated and modified rows as conflicts that must be resolved in some way.
- Conflict detection
- Maybe faster at the merge stage
- Maybe slower at the scan stage
Rows that exist on source but not on the destination can be due to:
- They were inserted in the source
- They were deleted in the destination
How to detect the difference?
Use the Session / Changeset feature
- Conflict detection
- Does not deal with schema differences
Use a modified Session / Changeset feature with these changes:
-
Detect schema differences
-
Copy rows directly instead of generating SQL commands
- Conflict detection
- Deals with schema differences
- Maybe hard to implement
Just like option 4 but automatically choosing the best / faster merge approach (run SQL or copy rows directly)
- Conflict detection
- Deals with schema differences
- Maybe hard to implement
Either by:
-
Using our code in C
-
Using the SQLite VDBE
Notice that the SQL commands from option 1 come from the log / history and the others are generated by code. So the complexity and speed of execution may vary a lot.
(you can add your notes here bellow or participate in the discussion here)