From 21bc84fd893fc46690af7731388aaea487d24383 Mon Sep 17 00:00:00 2001 From: Zach Musgrave Date: Tue, 22 Jun 2021 19:43:40 -0700 Subject: [PATCH] Finished putting merge state into working set --- go/cmd/dolt/commands/gc.go | 2 +- go/cmd/dolt/commands/merge.go | 16 +++++++- go/libraries/doltcore/env/actions/commit.go | 21 ++++++----- go/libraries/doltcore/env/environment.go | 24 +++++++----- go/libraries/doltcore/env/repo_state.go | 37 +++++++++---------- .../doltcore/mvdata/table_data_loc.go | 2 +- .../doltcore/sqle/dfunctions/dolt_commit.go | 7 +++- .../doltcore/sqle/dfunctions/dolt_merge.go | 14 ++++--- .../doltcore/sqle/session_repo_state.go | 6 +-- go/store/datas/workingset.go | 4 ++ 10 files changed, 81 insertions(+), 52 deletions(-) diff --git a/go/cmd/dolt/commands/gc.go b/go/cmd/dolt/commands/gc.go index 907a9fc3be..78eb9f6523 100644 --- a/go/cmd/dolt/commands/gc.go +++ b/go/cmd/dolt/commands/gc.go @@ -114,7 +114,7 @@ func (cmd GarbageCollectionCmd) Exec(ctx context.Context, commandStr string, arg return HandleVErrAndExitCode(verr, usage) } - keepers, err := env.GetGCKeepers(ctx, dEnv.RepoStateReader(), dEnv.DoltDB) + keepers, err := env.GetGCKeepers(ctx, dEnv) if err != nil { verr = errhand.BuildDError("an error occurred while saving working set").AddCause(err).Build() return HandleVErrAndExitCode(verr, usage) diff --git a/go/cmd/dolt/commands/merge.go b/go/cmd/dolt/commands/merge.go index 87ed22be3c..d79a2dee9f 100644 --- a/go/cmd/dolt/commands/merge.go +++ b/go/cmd/dolt/commands/merge.go @@ -92,7 +92,13 @@ func (cmd MergeCmd) Exec(ctx context.Context, commandStr string, args []string, var verr errhand.VerboseError if apr.Contains(cli.AbortParam) { - if !dEnv.IsMergeActive() { + mergeActive, err := dEnv.IsMergeActive(ctx) + if err != nil { + cli.PrintErrln("fatal: %s", err.Error()) + return 1 + } + + if !mergeActive { cli.PrintErrln("fatal: There is no merge to abort") return 1 } @@ -110,6 +116,12 @@ func (cmd MergeCmd) Exec(ctx context.Context, commandStr string, args []string, root, verr = GetWorkingWithVErr(dEnv) if verr == nil { + mergeActive, err := dEnv.IsMergeActive(ctx) + if err != nil { + cli.PrintErrln("error: Merging is not possible because you have not committed an active merge: %s", err.Error()) + return 1 + } + if has, err := root.HasConflicts(ctx); err != nil { verr = errhand.BuildDError("error: failed to get conflicts").AddCause(err).Build() } else if has { @@ -118,7 +130,7 @@ func (cmd MergeCmd) Exec(ctx context.Context, commandStr string, args []string, cli.Println("hint: as appropriate to mark resolution and make a commit.") cli.Println("fatal: Exiting because of an unresolved conflict.") return 1 - } else if dEnv.IsMergeActive() { + } else if mergeActive { cli.Println("error: Merging is not possible because you have not committed an active merge.") cli.Println("hint: add affected tables using 'dolt add ' and commit using 'dolt commit -m '") cli.Println("fatal: Exiting because of active merge") diff --git a/go/libraries/doltcore/env/actions/commit.go b/go/libraries/doltcore/env/actions/commit.go index 9b45194efe..6e2392555a 100644 --- a/go/libraries/doltcore/env/actions/commit.go +++ b/go/libraries/doltcore/env/actions/commit.go @@ -84,7 +84,12 @@ func CommitStaged(ctx context.Context, workingRoot *doltdb.RootValue, dbData env stagedTblNames = append(stagedTblNames, n) } - if len(staged) == 0 && !rsr.IsMergeActive() && !props.AllowEmpty { + mergeActive, err := rsr.IsMergeActive(ctx) + if err != nil { + return "", err + } + + if len(staged) == 0 && !mergeActive && !props.AllowEmpty { _, notStagedDocs, err := diff.GetDocDiffs(ctx, ddb, workingRoot, rsr, drw) if err != nil { return "", err @@ -92,8 +97,8 @@ func CommitStaged(ctx context.Context, workingRoot *doltdb.RootValue, dbData env return "", NothingStaged{notStaged, notStagedDocs} } - var mergeCmSpec []*doltdb.CommitSpec - if rsr.IsMergeActive() { + var mergeParentCommits []*doltdb.Commit + if mergeActive { inConflict, err := workingRoot.TablesInConflict(ctx) if err != nil { return "", err @@ -102,13 +107,12 @@ func CommitStaged(ctx context.Context, workingRoot *doltdb.RootValue, dbData env return "", NewTblInConflictError(inConflict) } - spec, err := doltdb.NewCommitSpec(rsr.GetMergeCommit()) - + commit, err := rsr.GetMergeCommit(ctx) if err != nil { - panic("Corrupted repostate. Active merge state is not valid.") + return "", err } - mergeCmSpec = []*doltdb.CommitSpec{spec} + mergeParentCommits = []*doltdb.Commit{commit} } srt, err := env.StagedRoot(ctx, ddb, rsr) @@ -169,8 +173,7 @@ func CommitStaged(ctx context.Context, workingRoot *doltdb.RootValue, dbData env } // DoltDB resolves the current working branch head ref to provide a parent commit. - // Any commit specs in mergeCmSpec are also resolved and added. - c, err := ddb.CommitWithParentSpecs(ctx, h, rsr.CWBHeadRef(), mergeCmSpec, meta) + c, err := ddb.CommitWithParentCommits(ctx, h, rsr.CWBHeadRef(), mergeParentCommits, meta) if err != nil { return "", err diff --git a/go/libraries/doltcore/env/environment.go b/go/libraries/doltcore/env/environment.go index 89b35553a3..9f38799056 100644 --- a/go/libraries/doltcore/env/environment.go +++ b/go/libraries/doltcore/env/environment.go @@ -443,16 +443,17 @@ func (r *repoStateReader) StagedHash() hash.Hash { return hash.Parse(r.dEnv.RepoState.staged) } -func (r *repoStateReader) IsMergeActive() bool { - return r.dEnv.RepoState.Merge != nil +func (r *repoStateReader) IsMergeActive(ctx context.Context) (bool, error) { + return r.dEnv.IsMergeActive(ctx) } -func (r *repoStateReader) GetMergeCommit() string { - return r.dEnv.RepoState.Merge.Commit -} +func (r *repoStateReader) GetMergeCommit(ctx context.Context) (*doltdb.Commit, error) { + ws, err := r.dEnv.WorkingSet(ctx) + if err != nil { + return nil, err + } -func (r *repoStateReader) GetPreMergeWorking() string { - return r.dEnv.RepoState.Merge.PreMergeWorking + return ws.MergeState().Commit(), nil } func (dEnv *DoltEnv) RepoStateReader() RepoStateReader { @@ -661,8 +662,13 @@ func (dEnv *DoltEnv) PutTableToWorking(ctx context.Context, sch schema.Schema, r return dEnv.UpdateWorkingRoot(ctx, newRoot) } -func (dEnv *DoltEnv) IsMergeActive() bool { - return dEnv.RepoState.Merge != nil +func (dEnv *DoltEnv) IsMergeActive(ctx context.Context) (bool, error) { + ws, err := dEnv.WorkingSet(ctx) + if err != nil { + return false, err + } + + return ws.MergeActive(), nil } func (dEnv *DoltEnv) GetTablesWithConflicts(ctx context.Context) ([]string, error) { diff --git a/go/libraries/doltcore/env/repo_state.go b/go/libraries/doltcore/env/repo_state.go index c9acc32b8a..6b0014993d 100644 --- a/go/libraries/doltcore/env/repo_state.go +++ b/go/libraries/doltcore/env/repo_state.go @@ -17,7 +17,6 @@ package env import ( "context" "encoding/json" - "fmt" "github.com/dolthub/dolt/go/cmd/dolt/errhand" "github.com/dolthub/dolt/go/libraries/doltcore/doltdb" @@ -30,12 +29,12 @@ import ( type RepoStateReader interface { CWBHeadRef() ref.DoltRef CWBHeadSpec() *doltdb.CommitSpec + // TODO: rreplace with commit CWBHeadHash(ctx context.Context) (hash.Hash, error) WorkingRoot(ctx context.Context) (*doltdb.RootValue, error) StagedRoot(ctx context.Context) (*doltdb.RootValue, error) - IsMergeActive() bool - GetMergeCommit() string - GetPreMergeWorking() string + IsMergeActive(ctx context.Context) (bool, error) + GetMergeCommit(ctx context.Context) (*doltdb.Commit, error) } type RepoStateWriter interface { @@ -272,8 +271,8 @@ func MergeWouldStompChanges(ctx context.Context, workingRoot *doltdb.RootValue, // GetGCKeepers queries |rsr| to find a list of values that need to be temporarily saved during GC. // TODO: move this out of repo_state.go -func GetGCKeepers(ctx context.Context, rsr RepoStateReader, ddb *doltdb.DoltDB) ([]hash.Hash, error) { - workingRoot, err := rsr.WorkingRoot(ctx) +func GetGCKeepers(ctx context.Context, env *DoltEnv) ([]hash.Hash, error) { + workingRoot, err := env.WorkingRoot(ctx) if err != nil { return nil, err } @@ -283,7 +282,7 @@ func GetGCKeepers(ctx context.Context, rsr RepoStateReader, ddb *doltdb.DoltDB) return nil, err } - stagedRoot, err := rsr.StagedRoot(ctx) + stagedRoot, err := env.StagedRoot(ctx) if err != nil { return nil, err } @@ -298,32 +297,30 @@ func GetGCKeepers(ctx context.Context, rsr RepoStateReader, ddb *doltdb.DoltDB) stagedHash, } - if rsr.IsMergeActive() { - spec, err := doltdb.NewCommitSpec(rsr.GetMergeCommit()) - if err != nil { - return nil, err - } - - cm, err := ddb.Resolve(ctx, spec, nil) + mergeActive, err := env.IsMergeActive(ctx) + if err != nil { + return nil, err + } + + if mergeActive { + ws, err := env.WorkingSet(ctx) if err != nil { return nil, err } + cm := ws.MergeState().Commit() ch, err := cm.HashOf() if err != nil { return nil, err } - pmw := hash.Parse(rsr.GetPreMergeWorking()) - val, err := ddb.ValueReadWriter().ReadValue(ctx, pmw) + pmw := ws.MergeState().PreMergeWorkingRoot() + pmwh, err := pmw.HashOf() if err != nil { return nil, err } - if val == nil { - return nil, fmt.Errorf("MergeState.PreMergeWorking is a dangling hash") - } - keepers = append(keepers, ch, pmw) + keepers = append(keepers, ch, pmwh) } return keepers, nil diff --git a/go/libraries/doltcore/mvdata/table_data_loc.go b/go/libraries/doltcore/mvdata/table_data_loc.go index 4a318f6b37..19f7d7f3a0 100644 --- a/go/libraries/doltcore/mvdata/table_data_loc.go +++ b/go/libraries/doltcore/mvdata/table_data_loc.go @@ -299,7 +299,7 @@ func (te *tableEditorWriteCloser) GC(ctx context.Context) error { return err } - keepers, err := env.GetGCKeepers(ctx, te.dEnv.RepoStateReader(), te.dEnv.DoltDB) + keepers, err := env.GetGCKeepers(ctx, te.dEnv) if err != nil { return err } diff --git a/go/libraries/doltcore/sqle/dfunctions/dolt_commit.go b/go/libraries/doltcore/sqle/dfunctions/dolt_commit.go index 98a2f87305..94458e35a2 100644 --- a/go/libraries/doltcore/sqle/dfunctions/dolt_commit.go +++ b/go/libraries/doltcore/sqle/dfunctions/dolt_commit.go @@ -80,9 +80,14 @@ func (d DoltCommitFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) return nil, fmt.Errorf("Cannot commit an empty commit. See the --allow-empty if you want to.") } + mergeActive, err := rsr.IsMergeActive(ctx) + if err != nil { + return nil, err + } + // Check if there are no changes in the working set but the -a flag is true. // The -a flag is fine when a merge is active or there are staged changes as result of a merge or an add. - if allFlag && !hasWorkingSetChanges(rsr) && !allowEmpty && !rsr.IsMergeActive() && !hasStagedChanges { + if allFlag && !hasWorkingSetChanges(rsr) && !allowEmpty && !mergeActive && !hasStagedChanges { return nil, fmt.Errorf("Cannot commit an empty commit. See the --allow-empty if you want to.") } diff --git a/go/libraries/doltcore/sqle/dfunctions/dolt_merge.go b/go/libraries/doltcore/sqle/dfunctions/dolt_merge.go index e859d3b55d..7acf8f8a9f 100644 --- a/go/libraries/doltcore/sqle/dfunctions/dolt_merge.go +++ b/go/libraries/doltcore/sqle/dfunctions/dolt_merge.go @@ -68,9 +68,10 @@ func (d DoltMergeFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) } if apr.Contains(cli.AbortParam) { - if !dbData.Rsr.IsMergeActive() { - return 1, fmt.Errorf("fatal: There is no merge to abort") - } + // TODO: fix me (get merge state from session) + // if !dbData.Rsr.IsMergeActive() { + // return 1, fmt.Errorf("fatal: There is no merge to abort") + // } err = abortMerge(ctx, dbData) @@ -103,9 +104,10 @@ func (d DoltMergeFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) return 1, doltdb.ErrUnresolvedConflicts } - if dbData.Rsr.IsMergeActive() { - return 1, doltdb.ErrMergeActive - } + // TODO: fix me (get merge state from session) + // if dbData.Rsr.IsMergeActive() { + // return 1, doltdb.ErrMergeActive + // } head, hh, headRoot, err := getHead(ctx, sess, dbName) if err != nil { diff --git a/go/libraries/doltcore/sqle/session_repo_state.go b/go/libraries/doltcore/sqle/session_repo_state.go index 36a70cc7d2..4b54572f50 100755 --- a/go/libraries/doltcore/sqle/session_repo_state.go +++ b/go/libraries/doltcore/sqle/session_repo_state.go @@ -73,15 +73,15 @@ func (s SessionRepoStateReader) StagedHash() hash.Hash { panic("implement me") } -func (s SessionRepoStateReader) IsMergeActive() bool { +func (s SessionRepoStateReader) IsMergeActive(ctx context.Context) (bool, error) { panic("implement me") } -func (s SessionRepoStateReader) GetMergeCommit() string { +func (s SessionRepoStateReader) GetMergeCommit(ctx context.Context) (*doltdb.Commit, error) { panic("implement me") } -func (s SessionRepoStateReader) GetPreMergeWorking() string { +func (s SessionRepoStateReader) GetPreMergeWorking(ctx context.Context) (*doltdb.RootValue, error) { panic("implement me") } diff --git a/go/store/datas/workingset.go b/go/store/datas/workingset.go index 116d18e864..0fce400e6e 100755 --- a/go/store/datas/workingset.go +++ b/go/store/datas/workingset.go @@ -87,6 +87,10 @@ func NewWorkingSet(_ context.Context, workingRef types.Ref, stagedRef, mergeStat return types.NewStruct(workingRef.Format(), WorkingSetName, fields) } +func NewMergeState(_ context.Context, preMergeWorking types.Ref, commit types.Struct) (types.Struct, error) { + return mergeStateTemplate.NewStruct(preMergeWorking.Format(), []types.Value{commit, preMergeWorking}) +} + func IsWorkingSet(v types.Value) (bool, error) { if s, ok := v.(types.Struct); !ok { return false, nil