Omnigraph
Branching

Merge

Three-way merge for combining divergent branches.

Merging combines the changes from one branch into another. Omnigraph uses a three-way merge algorithm — the same strategy used by git — to detect conflicts and apply non-conflicting changes automatically.

Merge command

omnigraph branch merge --uri ./repo.omni feature-x --into main

This merges the changes from feature-x into main. After a successful merge, main advances to a new snapshot that includes both its own changes and those from feature-x.

Add --json for structured output:

omnigraph branch merge --uri ./repo.omni feature-x --into main --json

Three outcomes

Every merge resolves to one of three outcomes:

OutcomeMeaning
already_up_to_dateThe target branch already contains all changes from the source. Nothing to do.
fast_forwardThe target branch has no new changes since the fork point. The pointer moves forward.
mergedBoth branches have diverged. A three-way merge produces a new snapshot on the target.

How three-way merge works

When both branches have diverged from their common ancestor, Omnigraph performs a three-way merge:

1. Find the merge base

The merge base is the most recent snapshot shared by both branches — the point where they diverged. Omnigraph walks the snapshot history of both branches to find this common ancestor.

2. Diff each branch against the base

Two diffs are computed:

  • Source diff — what changed on feature-x since the merge base.
  • Target diff — what changed on main since the merge base.

Each diff is a set of per-row changes classified as inserts, updates, or deletes.

3. Apply non-conflicting changes

Changes that appear in only one diff are applied directly:

  • A row inserted only on the source branch is added to the target.
  • A row updated only on the source branch has its updates applied.
  • A row deleted only on the source branch is removed.

The same logic applies symmetrically for changes that appear only on the target side — those are already present and are preserved.

4. Detect conflicts

A conflict occurs when both branches modify the same data in incompatible ways. Omnigraph classifies conflicts into the following types:

Conflict typeDescription
Divergent updateBoth branches updated the same row with different values for the same property.
Delete vs. updateOne branch deleted a row that the other branch updated.
Duplicate insertBoth branches inserted a row with the same @key value but different data.
Orphan edgeAn edge references a node that was deleted on the other branch.
Constraint violationThe merged result would violate a schema constraint (e.g., @unique, @range).
Type mismatchA property was set to incompatible types across the two branches.
Cardinality violationThe merged edge set would exceed a declared cardinality limit.

When conflicts are detected, the merge fails and the conflict details are returned. The target branch is not modified.

Inspecting before merging

Before merging, you can read from both branches to understand what will change:

# Check the current state of main
omnigraph snapshot ./repo.omni --branch main

# Check the state of the source branch
omnigraph snapshot ./repo.omni --branch feature-x

Run queries against both branches to compare results:

omnigraph read ./repo.omni \
    --query queries.gq \
    --name count_tasks \
    --branch main

omnigraph read ./repo.omni \
    --query queries.gq \
    --name count_tasks \
    --branch feature-x

This lets you verify the effect of a merge before committing to it.

On this page