Structural three-way table merging with explicit decisions and no invented cell values.
moon add cn-hww/mntablemerge@0.1.0moon run scripts/demo.mbtx
moon run cmd/main -- merge examples/airports/base.csv examples/airports/ours.csv examples/airports/theirs.csv --key id
moon run cmd/main -- merge examples/airports/base.csv examples/airports/structure-ours.csv examples/airports/structure-theirs.csv --key id --report
moon run cmd/main -- merge examples/airports/base.csv examples/airports/structure-ours.csv examples/airports/structure-theirs.csv --key id --decisions examples/airports/decisions.jsonlet base = @tablemerge.parse_csv("id,value\nx,old\n")
let ours = @tablemerge.parse_csv("id,value\nx,ours\n")
let theirs = @tablemerge.parse_csv("id,value\nx,theirs\n")
let plan = @tablemerge.merge(base, ours, theirs, key=["id"])
let reviewed = @tablemerge.resolve(plan, [{
target: @tablemerge.Cell(@tablemerge.RowKey(["x"]), "value"),
choice: @tablemerge.Value("reviewed"),
}])
let csv = reviewed.finish().table().to_csv()moon run scripts/verify.mbtxpub(all) suberror MergeError {
InvalidTable(String)
InvalidKey(String)
InvalidCsv(record~ : Int, column~ : Int, reason~ : String)
LimitExceeded(String)
InvalidDecision(String)
Unresolved(Int)
InvalidReview(String)
InvalidOrder(String)
InvalidLineage(String)
} derive(Debug)pub struct MergePlan {
// private fields
}pub struct MergedTable {
// private fields
}pub struct ReviewBundle {
// private fields
}fn ReviewBundle::changes_report(self : ReviewBundle, previous : ReviewBundle) -> Json raise MergeErrorfn ReviewBundle::changes_since(self : ReviewBundle, previous : ReviewBundle) -> Array[ReviewChange] raise MergeErrorfn ReviewBundle::combine(self : ReviewBundle, reviews : Array[ReviewBundle]) -> ReviewBundle raise MergeErrorfn ReviewBundle::replay(self : ReviewBundle, base : Table, ours : Table, theirs : Table, key~ : Array[String]) -> MergePlan raise MergeErrorfn ReviewBundle::resolve(self : ReviewBundle, decisions : Array[Decision]) -> ReviewBundle raise MergeErrorfn ReviewBundle::revise(self : ReviewBundle, edits : Array[ReviewEdit]) -> ReviewBundle raise MergeErrorpub(all) struct ReviewChange {
target : Target
before : Resolution?
after : Resolution?
} derive(Eq, Debug)pub struct UniqueReview {
// private fields
}fn UniqueReview::changes_report(self : UniqueReview, previous : UniqueReview) -> Json raise MergeErrorfn UniqueReview::new(review : ReviewBundle, rules : Array[UniqueRule]) -> UniqueReview raise MergeErrorfn UniqueReview::repair(self : UniqueReview, decisions : Array[Decision]) -> UniqueReview raise MergeErrorfn UniqueReview::replay(self : UniqueReview, base : Table, ours : Table, theirs : Table, key~ : Array[String]) -> UniqueReview raise MergeErrorfn UniqueReview::revise(self : UniqueReview, edits : Array[ReviewEdit]) -> UniqueReview raise MergeErrorfn UniqueReview::revise_repairs(self : UniqueReview, edits : Array[ReviewEdit]) -> UniqueReview raise MergeErrorfn merge(base : Table, ours : Table, theirs : Table, key~ : Array[String], row_order? : RowOrder, column_lineage? : Array[ColumnLineage], row_lineage? : Array[RowLineage], column_evolution? : Array[ColumnEvolution]) -> MergePlan raise MergeErrorInstall
Download zipStructural three-way table merging with explicit decisions and no invented cell values.