go/{doltcore/merge, store}: refactored MergeRoots to return conflicts, serialization method for unmergable tables

This commit is contained in:
Andy Arthur
2023-04-18 16:43:06 -07:00
parent abe3fdbcdc
commit 474730af17
18 changed files with 134 additions and 82 deletions
+3 -3
View File
@@ -217,13 +217,13 @@ func getCherryPickedRootValue(ctx context.Context, dEnv *env.DoltEnv, workingRoo
// use parent of cherry-pick as ancestor to merge
mo := merge.MergeOpts{IsCherryPick: true}
mergedRoot, mergeStats, err := merge.MergeRoots(ctx, workingRoot, cherryRoot, parentRoot, cherryCm, parentCm, opts, mo)
result, err := merge.MergeRoots(ctx, workingRoot, cherryRoot, parentRoot, cherryCm, parentCm, opts, mo)
if err != nil {
return nil, "", err
}
var tablesWithConflict []string
for tbl, stats := range mergeStats {
for tbl, stats := range result.Stats {
if stats.Conflicts > 0 {
tablesWithConflict = append(tablesWithConflict, tbl)
}
@@ -234,5 +234,5 @@ func getCherryPickedRootValue(ctx context.Context, dEnv *env.DoltEnv, workingRoo
return nil, "", errors.New(fmt.Sprintf("conflicts in table {'%s'}", tblNames))
}
return mergedRoot, commitMsg, nil
return result.Root, commitMsg, nil
}
+3 -3
View File
@@ -153,13 +153,13 @@ func applyStashAtIdx(ctx context.Context, dEnv *env.DoltEnv, curWorkingRoot *dol
}
opts := editor.Options{Deaf: dEnv.BulkDbEaFactory(), Tempdir: tmpDir}
mergedRoot, mergeStats, err := merge.MergeRoots(ctx, curWorkingRoot, stashRoot, parentRoot, stashRoot, parentCommit, opts, merge.MergeOpts{IsCherryPick: false})
result, err := merge.MergeRoots(ctx, curWorkingRoot, stashRoot, parentRoot, stashRoot, parentCommit, opts, merge.MergeOpts{IsCherryPick: false})
if err != nil {
return false, err
}
var tablesWithConflict []string
for tbl, stats := range mergeStats {
for tbl, stats := range result.Stats {
if stats.Conflicts > 0 {
tablesWithConflict = append(tablesWithConflict, tbl)
}
@@ -173,7 +173,7 @@ func applyStashAtIdx(ctx context.Context, dEnv *env.DoltEnv, curWorkingRoot *dol
return false, nil
}
err = dEnv.UpdateWorkingRoot(ctx, mergedRoot)
err = dEnv.UpdateWorkingRoot(ctx, result.Root)
if err != nil {
return false, err
}
+5 -5
View File
@@ -353,7 +353,7 @@ func (rcv *MergeState) FromCommitSpecStr() []byte {
return nil
}
func (rcv *MergeState) SchemaConflictTables(j int) []byte {
func (rcv *MergeState) UnmergableTables(j int) []byte {
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
if o != 0 {
a := rcv._tab.Vector(o)
@@ -362,7 +362,7 @@ func (rcv *MergeState) SchemaConflictTables(j int) []byte {
return nil
}
func (rcv *MergeState) SchemaConflictTablesLength() int {
func (rcv *MergeState) UnmergableTablesLength() int {
o := flatbuffers.UOffsetT(rcv._tab.Offset(10))
if o != 0 {
return rcv._tab.VectorLen(o)
@@ -390,10 +390,10 @@ func MergeStateStartFromCommitAddrVector(builder *flatbuffers.Builder, numElems
func MergeStateAddFromCommitSpecStr(builder *flatbuffers.Builder, fromCommitSpecStr flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(2, flatbuffers.UOffsetT(fromCommitSpecStr), 0)
}
func MergeStateAddSchemaConflictTables(builder *flatbuffers.Builder, schemaConflictTables flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(schemaConflictTables), 0)
func MergeStateAddUnmergableTables(builder *flatbuffers.Builder, unmergableTables flatbuffers.UOffsetT) {
builder.PrependUOffsetTSlot(3, flatbuffers.UOffsetT(unmergableTables), 0)
}
func MergeStateStartSchemaConflictTablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
func MergeStateStartUnmergableTablesVector(builder *flatbuffers.Builder, numElems int) flatbuffers.UOffsetT {
return builder.StartVector(4, numElems, 4)
}
func MergeStateEnd(builder *flatbuffers.Builder) flatbuffers.UOffsetT {
+14 -7
View File
@@ -35,10 +35,11 @@ type MergeState struct {
commitSpecStr string
preMergeWorking *RootValue
sourceCommit hash.Hash
schemaConflictTables []string
sourceCommit hash.Hash
unmergableTables []string
}
// todo(andy): this might make more sense in pkg merge
type SchemaConflict struct {
ToSch, FromSch schema.Schema
ToFks, FromFks []ForeignKey
@@ -78,7 +79,7 @@ func (m MergeState) PreMergeWorkingRoot() *RootValue {
type SchemaConflictFn func(table string, conflict SchemaConflict) error
func (m MergeState) HasSchemaConflicts() bool {
return len(m.schemaConflictTables) > 0
return len(m.unmergableTables) > 0
}
func (m MergeState) IterSchemaConflicts(ctx context.Context, ddb *DoltDB, cb SchemaConflictFn) error {
@@ -111,7 +112,7 @@ func (m MergeState) IterSchemaConflicts(ctx context.Context, ddb *DoltDB, cb Sch
return err
}
for _, name := range m.schemaConflictTables {
for _, name := range m.unmergableTables {
var toTbl, fromTbl *Table
if toTbl, _, err = to.GetTable(ctx, name); err != nil {
return err
@@ -286,10 +287,16 @@ func NewWorkingSet(ctx context.Context, name string, vrw types.ValueReadWriter,
return nil, err
}
unmergableTables, err := dsws.MergeState.UnmergableTables(ctx, vrw)
if err != nil {
return nil, err
}
mergeState = &MergeState{
commit: commit,
commitSpecStr: commitSpec,
preMergeWorking: preMergeWorkingRoot,
commit: commit,
commitSpecStr: commitSpec,
preMergeWorking: preMergeWorkingRoot,
unmergableTables: unmergableTables,
}
}
+8 -4
View File
@@ -182,18 +182,22 @@ func ExecuteMerge(ctx context.Context, dEnv *env.DoltEnv, spec *MergeSpec) (map[
return nil, err
}
opts := editor.Options{Deaf: dEnv.BulkDbEaFactory(), Tempdir: tmpDir}
mergedRoot, tblToStats, err := MergeCommits(ctx, spec.HeadC, spec.MergeC, opts)
result, err := MergeCommits(ctx, spec.HeadC, spec.MergeC, opts)
if err != nil {
switch err {
case doltdb.ErrUpToDate:
return tblToStats, fmt.Errorf("already up to date; %w", err)
return result.Stats, fmt.Errorf("already up to date; %w", err)
case ErrFastForward:
panic("fast forward merge")
}
return tblToStats, err
return result.Stats, err
}
return tblToStats, mergedRootToWorking(ctx, spec.Squash, dEnv, mergedRoot, spec.WorkingDiffs, spec.MergeC, spec.MergeCSpecStr, tblToStats)
err = mergedRootToWorking(ctx, spec.Squash, dEnv, result.Root, spec.WorkingDiffs, spec.MergeC, spec.MergeCSpecStr, result.Stats)
if err != nil {
return nil, err
}
return result.Stats, nil
}
// TODO: change this to be functional and not write to repo state
+51 -28
View File
@@ -29,7 +29,6 @@ import (
var ErrFastForward = errors.New("fast forward")
var ErrTableDeletedAndModified = errors.New("conflict: table with same name deleted and modified ")
var ErrSchemaConflict = errors.New("schema conflict found, merge aborted. Please alter schema to prevent schema conflicts before merging")
// ErrCantOverwriteConflicts is returned when there are unresolved conflicts
// and the merge produces new conflicts. Because we currently don't have a model
@@ -45,30 +44,35 @@ var ErrMultipleViolationsForRow = errors.New("multiple violations for row not su
var ErrSameTblAddedTwice = goerrors.NewKind("table with same name '%s' added in 2 commits can't be merged")
func MergeCommits(ctx context.Context, commit, mergeCommit *doltdb.Commit, opts editor.Options) (*doltdb.RootValue, map[string]*MergeStats, error) {
func MergeCommits(ctx context.Context, commit, mergeCommit *doltdb.Commit, opts editor.Options) (*Result, error) {
ancCommit, err := doltdb.GetCommitAncestor(ctx, commit, mergeCommit)
if err != nil {
return nil, nil, err
return nil, err
}
ourRoot, err := commit.GetRootValue(ctx)
if err != nil {
return nil, nil, err
return nil, err
}
theirRoot, err := mergeCommit.GetRootValue(ctx)
if err != nil {
return nil, nil, err
return nil, err
}
ancRoot, err := ancCommit.GetRootValue(ctx)
if err != nil {
return nil, nil, err
return nil, err
}
return MergeRoots(ctx, ourRoot, theirRoot, ancRoot, mergeCommit, ancCommit, opts, MergeOpts{IsCherryPick: false})
}
type Result struct {
Root *doltdb.RootValue
SchemaConflicts []string
Stats map[string]*MergeStats
}
// MergeRoots three-way merges |ourRoot|, |theirRoot|, and |ancRoot| and returns
// the merged root. If any conflicts or constraint violations are produced they
// are stored in the merged root. If |ourRoot| already contains conflicts they
@@ -88,18 +92,18 @@ func MergeRoots(
theirs, ancestor doltdb.Rootish,
opts editor.Options,
mergeOpts MergeOpts,
) (*doltdb.RootValue, map[string]*MergeStats, error) {
) (*Result, error) {
var conflictStash *conflictStash
var violationStash *violationStash
var err error
if !types.IsFormat_DOLT(ourRoot.VRW().Format()) {
ourRoot, conflictStash, err = stashConflicts(ctx, ourRoot)
if err != nil {
return nil, nil, err
return nil, err
}
ancRoot, violationStash, err = stashViolations(ctx, ancRoot)
if err != nil {
return nil, nil, err
return nil, err
}
}
@@ -112,7 +116,7 @@ func MergeRoots(
tblNames, err := doltdb.UnionTableNames(ctx, ourRoot, theirRoot)
if err != nil {
return nil, nil, err
return nil, err
}
tblToStats := make(map[string]*MergeStats)
@@ -127,13 +131,16 @@ func MergeRoots(
// TODO: merge based on a more durable table identity that persists across renames
merger, err := NewMerger(ourRoot, theirRoot, ancRoot, theirs, ancestor, ourRoot.VRW(), ourRoot.NodeStore())
if err != nil {
return nil, nil, err
return nil, err
}
var schConflictTables []string
for _, tblName := range tblNames {
mergedTable, stats, err := merger.MergeTable(ctx, tblName, opts, mergeOpts)
schConflictTables, err = filterSchemaConflicts(schConflictTables, err)
if err != nil {
return nil, nil, err
return nil, err
}
if mergedTable != nil {
@@ -141,14 +148,14 @@ func MergeRoots(
mergedRoot, err = mergedRoot.PutTable(ctx, tblName, mergedTable)
if err != nil {
return nil, nil, err
return nil, err
}
continue
}
newRootHasTable, err := mergedRoot.HasTable(ctx, tblName)
if err != nil {
return nil, nil, err
return nil, err
}
if newRootHasTable {
@@ -157,7 +164,7 @@ func MergeRoots(
mergedRoot, err = mergedRoot.RemoveTables(ctx, false, false, tblName)
if err != nil {
return nil, nil, err
return nil, err
}
} else {
@@ -171,57 +178,73 @@ func MergeRoots(
mergedFKColl, conflicts, err := ForeignKeysMerge(ctx, mergedRoot, ourRoot, theirRoot, ancRoot)
if err != nil {
return nil, nil, err
return nil, err
}
if len(conflicts) > 0 {
return nil, nil, fmt.Errorf("foreign key conflicts")
return nil, fmt.Errorf("foreign key conflicts")
}
mergedRoot, err = mergedRoot.PutForeignKeyCollection(ctx, mergedFKColl)
if err != nil {
return nil, nil, err
return nil, err
}
h, err := merger.rightSrc.HashOf()
if err != nil {
return nil, nil, err
return nil, err
}
mergedRoot, _, err = AddForeignKeyViolations(ctx, mergedRoot, ancRoot, nil, h)
if err != nil {
return nil, nil, err
return nil, err
}
if types.IsFormat_DOLT(ourRoot.VRW().Format()) {
err = getConstraintViolationStats(ctx, mergedRoot, tblToStats)
if err != nil {
return nil, nil, err
return nil, err
}
return mergedRoot, tblToStats, nil
return &Result{
Root: mergedRoot,
SchemaConflicts: schConflictTables,
Stats: tblToStats,
}, nil
}
mergedRoot, err = mergeCVsWithStash(ctx, mergedRoot, violationStash)
if err != nil {
return nil, nil, err
return nil, err
}
err = getConstraintViolationStats(ctx, mergedRoot, tblToStats)
if err != nil {
return nil, nil, err
return nil, err
}
mergedHasConflicts := checkForConflicts(tblToStats)
if !conflictStash.Empty() && mergedHasConflicts {
return nil, nil, ErrCantOverwriteConflicts
return nil, ErrCantOverwriteConflicts
} else if !conflictStash.Empty() {
mergedRoot, err = applyConflictStash(ctx, conflictStash.Stash, mergedRoot)
if err != nil {
return nil, nil, err
return nil, err
}
}
return mergedRoot, tblToStats, nil
return &Result{
Root: mergedRoot,
SchemaConflicts: schConflictTables,
Stats: tblToStats,
}, nil
}
func filterSchemaConflicts(conflicts []string, err error) ([]string, error) {
if sc, ok := err.(SchemaConflict); ok {
conflicts = append(conflicts, sc.TableName)
err = nil
}
return conflicts, err
}
// mergeCVsWithStash merges the table constraint violations in |stash| with |root|.
+3 -4
View File
@@ -126,10 +126,9 @@ func (rm *RootMerger) MergeTable(ctx context.Context, tblName string, opts edito
mergeSch, schConflicts, err := SchemaMerge(ctx, tm.vrw.Format(), tm.leftSch, tm.rightSch, tm.ancSch, tblName)
if err != nil {
return nil, nil, err
}
if schConflicts.Count() != 0 {
// error on schema conflicts for now
return nil, nil, fmt.Errorf("%w.\n%s", ErrSchemaConflict, schConflicts.AsError().Error())
} else if schConflicts.Count() > 0 {
// handle schema conflicts above
return nil, nil, schConflicts
}
if types.IsFormat_DOLT(tm.vrw.Format()) {
+9 -6
View File
@@ -45,15 +45,18 @@ type SchemaConflict struct {
ChkConflicts []ChkConflict
}
var EmptySchConflicts = SchemaConflict{}
var _ error = SchemaConflict{}
func (sc SchemaConflict) Count() int {
return len(sc.ColConflicts) + len(sc.IdxConflicts) + len(sc.ChkConflicts)
}
func (sc SchemaConflict) AsError() error {
func (sc SchemaConflict) Error() string {
var b strings.Builder
b.WriteString(fmt.Sprintf("schema conflicts for table %s:\n", sc.TableName))
b.WriteString("merge aborted: schema conflict found for table ")
b.WriteString(sc.TableName)
b.WriteString("\n please resolve schema conflicts before merging")
for _, c := range sc.ColConflicts {
b.WriteString(fmt.Sprintf("\t%s\n", c.String()))
}
@@ -63,7 +66,7 @@ func (sc SchemaConflict) AsError() error {
for _, c := range sc.ChkConflicts {
b.WriteString(fmt.Sprintf("\t%s\n", c.String()))
}
return fmt.Errorf(b.String())
return b.String()
}
type ColConflict struct {
@@ -136,7 +139,7 @@ func SchemaMerge(ctx context.Context, format *types.NomsBinFormat, ourSch, their
var mergedCC *schema.ColCollection
mergedCC, sc.ColConflicts, err = mergeColumns(ourSch.GetAllCols(), theirSch.GetAllCols(), ancSch.GetAllCols())
if err != nil {
return nil, EmptySchConflicts, err
return nil, SchemaConflict{}, err
}
if len(sc.ColConflicts) > 0 {
return nil, sc, nil
@@ -168,7 +171,7 @@ func SchemaMerge(ctx context.Context, format *types.NomsBinFormat, ourSch, their
var mergedChks []schema.Check
mergedChks, sc.ChkConflicts, err = mergeChecks(ctx, ourSch.Checks(), theirSch.Checks(), ancSch.Checks())
if err != nil {
return nil, EmptySchConflicts, err
return nil, SchemaConflict{}, err
}
if len(sc.ChkConflicts) > 0 {
return nil, sc, nil
+6 -3
View File
@@ -68,16 +68,19 @@ func Revert(ctx context.Context, ddb *doltdb.DoltDB, root *doltdb.RootValue, hea
return nil, "", err
}
root, _, err = MergeRoots(ctx, root, theirRoot, baseRoot, parentCM, baseCommit, opts, MergeOpts{IsCherryPick: false})
var result *Result
result, err = MergeRoots(ctx, root, theirRoot, baseRoot, parentCM, baseCommit, opts, MergeOpts{IsCherryPick: false})
if err != nil {
return nil, "", err
}
if ok, err := root.HasConflicts(ctx); err != nil {
root = result.Root
if ok, err := result.Root.HasConflicts(ctx); err != nil {
return nil, "", err
} else if ok {
return nil, "", fmt.Errorf("revert currently does not handle conflicts")
}
if ok, err := root.HasConstraintViolations(ctx); err != nil {
if ok, err := result.Root.HasConstraintViolations(ctx); err != nil {
return nil, "", err
} else if ok {
return nil, "", fmt.Errorf("revert currently does not handle constraint violations")
@@ -687,10 +687,10 @@ func testMergeForeignKeys(t *testing.T, test mergeForeignKeyTest) {
opts := editor.TestEditorOptions(dEnv.DoltDB.ValueReadWriter())
mo := merge.MergeOpts{IsCherryPick: false}
mergedRoot, _, err := merge.MergeRoots(ctx, mainRoot, otherRoot, ancRoot, mainWS, otherWS, opts, mo)
result, err := merge.MergeRoots(ctx, mainRoot, otherRoot, ancRoot, mainWS, otherWS, opts, mo)
assert.NoError(t, err)
fkc, err := mergedRoot.GetForeignKeyCollection(ctx)
fkc, err := result.Root.GetForeignKeyCollection(ctx)
assert.NoError(t, err)
assert.Equal(t, test.fkColl.Count(), fkc.Count())
@@ -551,12 +551,12 @@ func testSchemaMerge(t *testing.T, tests []schemaMergeTest) {
var eo editor.Options
eo = eo.WithDeaf(editor.NewInMemDeaf(a.VRW()))
// attempt merge before skipping to assert no panics
root, _, err := merge.MergeRoots(ctx, l, r, a, rootish{r}, rootish{a}, eo, mo)
result, err := merge.MergeRoots(ctx, l, r, a, rootish{r}, rootish{a}, eo, mo)
maybeSkip(t, a.VRW().Format(), test)
require.NoError(t, err)
exp, err := m.MapTableHashes(ctx)
assert.NoError(t, err)
act, err := root.MapTableHashes(ctx)
act, err := result.Root.MapTableHashes(ctx)
assert.NoError(t, err)
assert.Equal(t, len(exp), len(act))
@@ -171,13 +171,13 @@ func cherryPick(ctx *sql.Context, dSess *dsess.DoltSession, roots doltdb.Roots,
// use parent of cherry-pick as ancestor root to merge
mo := merge.MergeOpts{IsCherryPick: true}
mergedRoot, mergeStats, err := merge.MergeRoots(ctx, roots.Working, cherryRoot, parentRoot, cherryCommit, parentCommit, dbState.EditOpts(), mo)
result, err := merge.MergeRoots(ctx, roots.Working, cherryRoot, parentRoot, cherryCommit, parentCommit, dbState.EditOpts(), mo)
if err != nil {
return nil, "", err
}
var tablesWithConflict []string
for tbl, stats := range mergeStats {
for tbl, stats := range result.Stats {
if stats.Conflicts > 0 {
tablesWithConflict = append(tablesWithConflict, tbl)
}
@@ -188,7 +188,7 @@ func cherryPick(ctx *sql.Context, dSess *dsess.DoltSession, roots doltdb.Roots,
return nil, "", fmt.Errorf("conflicts in table {'%s'}", tblNames)
}
workingRootHash, err = mergedRoot.HashOf()
workingRootHash, err = result.Root.HashOf()
if err != nil {
return nil, "", err
}
@@ -202,5 +202,5 @@ func cherryPick(ctx *sql.Context, dSess *dsess.DoltSession, roots doltdb.Roots,
return nil, "", err
}
return mergedRoot, cherryCommitMeta.Description, nil
return result.Root, cherryCommitMeta.Description, nil
}
@@ -243,8 +243,7 @@ func abortMerge(ctx *sql.Context, workingSet *doltdb.WorkingSet, roots doltdb.Ro
}
func executeMerge(ctx *sql.Context, squash bool, head, cm *doltdb.Commit, cmSpec string, ws *doltdb.WorkingSet, opts editor.Options) (*doltdb.WorkingSet, error) {
mergeRoot, mergeStats, err := merge.MergeCommits(ctx, head, cm, opts)
result, err := merge.MergeCommits(ctx, head, cm, opts)
if err != nil {
switch err {
case doltdb.ErrUpToDate:
@@ -255,8 +254,7 @@ func executeMerge(ctx *sql.Context, squash bool, head, cm *doltdb.Commit, cmSpec
return nil, err
}
}
return mergeRootToWorking(squash, ws, mergeRoot, cm, cmSpec, mergeStats)
return mergeRootToWorking(squash, ws, result.Root, cm, cmSpec, result.Stats)
}
func executeFFMerge(ctx *sql.Context, dbName string, squash bool, ws *doltdb.WorkingSet, dbData env.DbData, cm2 *doltdb.Commit) (*doltdb.WorkingSet, error) {
@@ -184,7 +184,7 @@ func doltCommit(ctx *sql.Context,
// updates). The merged root value becomes our new Staged root value which
// is the value which we are trying to commit.
start := time.Now()
pending.Roots.Staged, _, err = merge.MergeRoots(
result, err := merge.MergeRoots(
ctx,
pending.Roots.Staged,
curRootVal,
@@ -196,6 +196,7 @@ func doltCommit(ctx *sql.Context,
if err != nil {
return nil, nil, err
}
pending.Roots.Staged = result.Root
// We also need to update the working set to reflect the new staged root value
workingSet = workingSet.WithStagedRoot(pending.Roots.Staged)
@@ -321,7 +322,7 @@ func (tx *DoltTransaction) mergeRoots(
) (*doltdb.WorkingSet, error) {
if !rootsEqual(existingWorkingSet.WorkingRoot(), workingSet.WorkingRoot()) {
mergedRoot, _, err := merge.MergeRoots(
result, err := merge.MergeRoots(
ctx,
existingWorkingSet.WorkingRoot(),
workingSet.WorkingRoot(),
@@ -333,11 +334,11 @@ func (tx *DoltTransaction) mergeRoots(
if err != nil {
return nil, err
}
workingSet = workingSet.WithWorkingRoot(mergedRoot)
workingSet = workingSet.WithWorkingRoot(result.Root)
}
if !rootsEqual(existingWorkingSet.StagedRoot(), workingSet.StagedRoot()) {
mergedRoot, _, err := merge.MergeRoots(
result, err := merge.MergeRoots(
ctx,
existingWorkingSet.StagedRoot(),
workingSet.StagedRoot(),
@@ -349,7 +350,7 @@ func (tx *DoltTransaction) mergeRoots(
if err != nil {
return nil, err
}
workingSet = workingSet.WithStagedRoot(mergedRoot)
workingSet = workingSet.WithStagedRoot(result.Root)
}
return workingSet, nil
+1 -1
View File
@@ -37,7 +37,7 @@ table MergeState {
// for backwards compatibility.
from_commit_spec_str:string;
schema_conflict_tables:[string];
unmergable_tables:[string];
}
// KEEP THIS IN SYNC WITH fileidentifiers.go
+1 -1
View File
@@ -324,7 +324,7 @@ func LoadCommitAddr(ctx context.Context, vr types.ValueReader, addr hash.Hash) (
return nil, err
}
if v == nil {
return nil, errors.New("target commit (" + addr.String() + ") not found")
return nil, errors.New("target commit not found")
}
return commitFromValue(vr.Format(), v)
}
+12
View File
@@ -164,6 +164,7 @@ type MergeState struct {
preMergeWorkingAddr *hash.Hash
fromCommitAddr *hash.Hash
fromCommitSpec string
unmergableTables []string
nomsMergeStateRef *types.Ref
nomsMergeState *types.Struct
@@ -255,6 +256,13 @@ func (ms *MergeState) FromCommitSpec(ctx context.Context, vr types.ValueReader)
return string(commitSpecStr.(types.String)), nil
}
func (ms *MergeState) UnmergableTables(ctx context.Context, vr types.ValueReader) ([]string, error) {
if vr.Format().UsesFlatbuffers() {
return ms.unmergableTables, nil
}
return nil, errors.New("schema conflicts only supported for fmt __DOLT__")
}
type dsHead interface {
TypeName() string
Addr() hash.Hash
@@ -369,6 +377,10 @@ func (h serialWorkingSetHead) HeadWorkingSet() (*WorkingSetHead, error) {
}
*ret.MergeState.preMergeWorkingAddr = hash.New(mergeState.PreWorkingRootAddrBytes())
*ret.MergeState.fromCommitAddr = hash.New(mergeState.FromCommitAddrBytes())
ret.MergeState.unmergableTables = make([]string, mergeState.UnmergableTablesLength())
for i := range ret.MergeState.unmergableTables {
ret.MergeState.unmergableTables[i] = string(mergeState.UnmergableTables(i))
}
}
return &ret, nil
}
+2
View File
@@ -162,10 +162,12 @@ func workingset_flatbuffer(working hash.Hash, staged *hash.Hash, mergeState *Mer
prerootaddroff := builder.CreateByteVector((*mergeState.preMergeWorkingAddr)[:])
fromaddroff := builder.CreateByteVector((*mergeState.fromCommitAddr)[:])
fromspecoff := builder.CreateString(mergeState.fromCommitSpec)
unmergableoff := SerializeStringVector(builder, mergeState.unmergableTables)
serial.MergeStateStart(builder)
serial.MergeStateAddPreWorkingRootAddr(builder, prerootaddroff)
serial.MergeStateAddFromCommitAddr(builder, fromaddroff)
serial.MergeStateAddFromCommitSpecStr(builder, fromspecoff)
serial.MergeStateAddUnmergableTables(builder, unmergableoff)
mergeStateOff = serial.MergeStateEnd(builder)
}