Documentation
¶
Overview ¶
Package merge implements structural 3-way merge over zone trees for the `zonegit merge` operation. It compares base/ours/theirs trees by walking their entries in lockstep, resolving non-conflicting changes automatically and classifying conflicts (both-modified, deleted-modified, add-add). Storage I/O is limited to tree and blob reads; the merge itself is a pure function of the three root hashes.
Index ¶
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Conflict ¶
type Conflict struct {
Path []string
RRType string
Reason ConflictReason
Base store.Hash
Ours store.Hash
Theirs store.Hash
}
Conflict identifies a leaf that the 3-way merge could not auto-resolve.
Path is the sequence of DNS labels from the zone apex down to the containing tree (i.e. the same coordinate space as history.Change.Path). RRType is the leaf name (the RR type mnemonic such as "A", "MX").
Hashes are provided for diagnostics; ZeroHash means "absent on this side".
func MergeTrees ¶
func MergeTrees(ctx context.Context, s store.Storage, base, ours, theirs store.Hash) (store.Hash, []Conflict, error)
MergeTrees performs a 3-way merge of three trees rooted at base, ours, and theirs and returns the hash of the merged tree.
The merge is structural: corresponding sub-trees and leaves are matched by (kind, name). Per-leaf resolution rules are:
ours == theirs -> take that value ours == base -> take theirs (theirs changed) theirs == base -> take ours (ours changed) otherwise -> conflict, ours wins for the merged tree
Conflicts are reported in the returned slice (sorted by FQDN, RRType). The returned tree always has *some* value at every conflicted leaf (currently "ours") so that the caller can still write a merged tree to disk for inspection; callers should refuse to advance a branch when len(conflicts) > 0.
Any of base, ours, theirs may be ZeroHash (meaning "empty tree").
type ConflictReason ¶
type ConflictReason int
ConflictReason classifies why a 3-way merge could not auto-resolve a leaf.
const ( // ReasonBothModified: base, ours, and theirs are three distinct leaves. // At v1 we do not attempt member-level RRset merge; any divergent // modification of the same leaf is a conflict. ReasonBothModified ConflictReason = iota + 1 // ReasonDeletedModified: one branch deleted the leaf, the other modified // it. The user must choose which intent wins. ReasonDeletedModified // ReasonAddAdd: leaf was absent in base and both branches added it with // different content (different blob hashes). ReasonAddAdd )
func (ConflictReason) String ¶
func (r ConflictReason) String() string
String renders the reason in lowercase, dash-separated form.