Merge Reconciliation

CommitMergeAnalyzer is an additive, application-level supervisor over the public CommitDatabase API. The engine reduces concurrent streams mechanically and signals no conflict; this layer reconstructs a notion of conflict over a merge — already persisted, or computed from the two heads before it is written — and lets a caller make a chosen value survive. It adds no engine, storage-format, or runtime change.

When to use: reach for this family when the application, not the engine, must decide which value survives where two streams touched the same locus. If mechanical reduction is acceptable, none of this is needed.

See also

Supervised Reconciliation — the model, the headless identify / surface / reconcile triad, and its bounds.

Quick Start

const { CommitMergeAnalyzer, CommitMergeResolution } =
    require('@digitalsubstrate/dsviper');

const merge = db.mergeCommit('merge', ours, theirs);
const analysis = CommitMergeAnalyzer.analyzeMerge(db, merge);

// The supervisor decides per conflict; here, keep ours at every locus.
// A resolution pairs the conflict with the value to make survive at its path —
// oursValue() already reads that value at the conflict's locus.
const resolutions = analysis.conflicts().map(
    (c) => new CommitMergeResolution(c, c.oursValue().unwrap()));

const survivor = CommitMergeAnalyzer.reconcile(db, merge, resolutions, 'reconcile');

Accepting the merge for every conflict makes reconcile return the merge commit unchanged.

The same three steps run before the merge commit exists: analyzeVirtualMerge(db, ours, theirs) — whose analysis carries no anchor, so CommitMergeAnalysis.mergeCommit() is undefined — then reconcileState(mergeState, resolutions) to render the arbitrated state in memory (writing nothing), and materializeMerge(db, ours, theirs, resolutions, mergeLabel, survivalLabel) to write the merge and its survival child together. The merge state comes from CommitStateBuilder.mergeState(db, ours, theirs).

Key classes

Class

Purpose

Example

CommitMergeAnalyzer

Additive, post-merge 3-way reconciliation over a CommitDatabase

CommitMergeAnalysis

The result of a 3-way merge analysis

CommitMergeConflict

A single locus where one head’s intent did not survive the merge

CommitMergeResolution

A supervisor’s decree for one reconstructed conflict: the chosen value should survive at the conflict’s locus

The mirror of this page for the Python binding is Merge Reconciliation.

Classes

Class

Description

CommitMergeAnalysis

The result of a 3-way merge analysis

CommitMergeAnalyzer

Additive, post-merge 3-way reconciliation over a CommitDatabase

CommitMergeConflict

A single locus where one head’s intent did not survive the merge

CommitMergeDocument

All reconstructed loci of one document (attachment, key) — the unit reconcile operates on

CommitMergeResolution

A supervisor’s decree for one reconstructed conflict: the chosen value should survive at the conflict’s locus

Reference

class CommitMergeAnalysis()

The result of a 3-way merge analysis.

The merge base and the list of reconstructed conflicts between the two heads.

Note: Not directly instantiable.

exported from index.d

CommitMergeAnalysis.base()
Return the structural merge base commit identifier, or undefined when the

analysis fell back to a base-free 2-way scan.

Returns:

ValueCommitId | undefined

CommitMergeAnalysis.conflicts()

Return every reconstructed locus, flattened across documents.

Returns:

CommitMergeConflict[]

CommitMergeAnalysis.documents()
Return the list of CommitMergeDocument — the conflicts grouped per

document (attachment, key), the unit reconcile operates on.

Returns:

CommitMergeDocument[]

CommitMergeAnalysis.hasConflicts()
Return true if the analysis reconstructed at least one locus where an intent was

lost.

Returns:

boolean

CommitMergeAnalysis.mergeCommit()
Return the merge commit identifier this analysis read, or undefined for a

virtual (pre-merge) analysis computed without a persisted merge commit.

Returns:

ValueCommitId | undefined

CommitMergeAnalysis.ours()

Return the parent (ours) commit identifier.

Returns:

ValueCommitId

CommitMergeAnalysis.theirs()

Return the target (theirs) commit identifier.

Returns:

ValueCommitId

CommitMergeAnalysis.twoWay()
Return true when no unambiguous structural base existed and detection

fell back to a base-free 2-way divergence scan.

Returns:

boolean

class CommitMergeAnalyzer()
Additive, post-merge 3-way reconciliation over a CommitDatabase. Static methods only;

the Commit Engine itself is not modified.

It works around the reduction; it does not repair it. The engine has no notion of conflict, so what this class calls a conflict is reconstructed after the fact, by comparing the two heads against what the merge produced.

Note: Not directly instantiable.

exported from index.d

static CommitMergeAnalyzer.analyzeMerge(db, mergeCommit)
Read the state of mergeCommit in db and return a CommitMergeAnalysis: the loci where

one head’s intent did not survive the merge. 3-way when a unique structural base exists, base-free 2-way fallback otherwise. Throws when mergeCommit is not a merge commit.

Arguments:
  • db (CommitDatabase)

  • mergeCommit (ValueCommitId)

Returns:

CommitMergeAnalysis

static CommitMergeAnalyzer.analyzeVirtualMerge(db, ours, theirs)

Pre-merge analysis over db, without persisting a merge commit.

The same classification runs against the merge state (ours, theirs) would produce.

The loci are reconstructed against a merge that does not exist yet and may never be written. The result’s mergeCommit() is undefined, and it cannot feed reconcile until materialized.

Arguments:
  • db (CommitDatabase)

  • ours (ValueCommitId)

  • theirs (ValueCommitId)

Returns:

CommitMergeAnalysis

static CommitMergeAnalyzer.materializeMerge(db, ours, theirs, resolutions, mergeLabel, survivalLabel)

Pre-merge materialization in db.

Writes the Merge join of (ours, theirs) under mergeLabel, then the survival commit of resolutions against it under survivalLabel.

Returns (mergeCommit, survival); survival == mergeCommit when every decree accepts the merge.

Arguments:
  • db (CommitDatabase)

  • ours (ValueCommitId)

  • theirs (ValueCommitId)

  • resolutions (CommitMergeResolution[])

  • mergeLabel (string)

  • survivalLabel (string)

Returns:

[ValueCommitId, ValueCommitId]

static CommitMergeAnalyzer.mergeBase(db, a, b)
Return the structural merge base of a and b in db, or undefined when there is no

common ancestor or several maximal common ancestors (criss-cross).

Arguments:
  • db (CommitDatabase)

  • a (ValueCommitId)

  • b (ValueCommitId)

Returns:

ValueCommitId | undefined

static CommitMergeAnalyzer.reconcile(db, mergeCommit, resolutions, label)
Author the survival commit for mergeCommit in db under label: per document, copy the

merge state, place each decree of resolutions at its path, then diff against the merge state. Returns a Mutations commit child of mergeCommit, or mergeCommit itself when every decree accepts the merge (no surviving opcode).

Arguments:
  • db (CommitDatabase)

  • mergeCommit (ValueCommitId)

  • resolutions (CommitMergeResolution[])

  • label (string)

Returns:

ValueCommitId

static CommitMergeAnalyzer.reconcileState(mergeState, resolutions)
Pure compose: per document, copy mergeState, place each decree of resolutions at its

path, diff into a working CommitMutableState. No commit is written; the returned state is what a UI renders and edits live. reconcile is this followed by commitMutations.

Arguments:
  • mergeState (CommitState)

  • resolutions (CommitMergeResolution[])

Returns:

CommitMutableState

class CommitMergeConflict()

A single locus where one head’s intent did not survive the merge.

Anchored on a path, and reconstructed as base/ours/theirs/merged values.

Note: Not directly instantiable.

exported from index.d

CommitMergeConflict.attachment()

Return the attachment this locus belongs to.

Returns:

Attachment

CommitMergeConflict.baseValue()

Return the value at the merge base (nil in 2-way mode).

Returns:

ValueOptional

CommitMergeConflict.key()

Return the key of the document this locus was reconstructed in.

Returns:

ValueKey

CommitMergeConflict.mergedValue()

Return the value the merge actually produced at this locus.

Returns:

ValueOptional

CommitMergeConflict.oursValue()

Return the value on the parent (ours) side.

Returns:

ValueOptional

CommitMergeConflict.path()
Return the locus inside the document where the intent was lost (root

for a scalar attachment).

Returns:

PathConst

CommitMergeConflict.theirsValue()

Return the value on the target (theirs) side.

Returns:

ValueOptional

class CommitMergeDocument()
All reconstructed loci of one document (attachment, key) — the unit reconcile operates

on. Carries the whole merged document as context.

Note: Not directly instantiable.

exported from index.d

CommitMergeDocument.attachment()

Return the attachment of this document.

Returns:

Attachment

CommitMergeDocument.conflicts()

Return the list of CommitMergeConflict localised in this document.

Returns:

CommitMergeConflict[]

CommitMergeDocument.key()

Return the key of this document.

Returns:

ValueKey

CommitMergeDocument.mergedValue()

Return the whole merged document, as context for its conflicts.

Returns:

ValueOptional

class CommitMergeResolution(conflict, chosen)
A supervisor’s decree for one reconstructed conflict: the chosen value should survive at

the conflict’s locus. A root locus decrees the whole document.

exported from index.d

Arguments:
  • conflict (CommitMergeConflict)

  • chosen (Value)

CommitMergeResolution.chosen()

Return the dictated value at the conflict’s locus.

Returns:

Value

CommitMergeResolution.conflict()

Return the conflict this resolution decrees.

Returns:

CommitMergeConflict