Merge pull request #5943 from dolthub/nicktobey/detached_head

Don't panic when in detached head state.
This commit is contained in:
Nick Tobey
2023-05-18 16:43:53 -07:00
committed by GitHub
47 changed files with 443 additions and 121 deletions
+10 -3
View File
@@ -138,7 +138,10 @@ func printBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
return HandleVErrAndExitCode(errhand.BuildDError("error: failed to read refs from db").AddCause(err).Build(), nil)
}
currentBranch := dEnv.RepoStateReader().CWBHeadRef()
currentBranch, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError("error: failed to read refs from db").AddCause(err).Build(), nil)
}
sort.Slice(branches, func(i, j int) bool {
return branches[i].String() < branches[j].String()
})
@@ -172,7 +175,7 @@ func printBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
}
if verbose {
cm, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
cm, err := dEnv.DoltDB.Resolve(ctx, cs, currentBranch)
if err == nil {
h, err := cm.HashOf()
@@ -195,7 +198,11 @@ func printBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
}
func printCurrentBranch(dEnv *env.DoltEnv) int {
cli.Println(dEnv.RepoStateReader().CWBHeadRef().GetPath())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError(err.Error()).Build(), nil)
}
cli.Println(headRef.GetPath())
return 0
}
+16 -4
View File
@@ -119,7 +119,10 @@ func (cmd CheckoutCmd) Exec(ctx context.Context, commandStr string, args []strin
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError(err.Error()).Build(), usagePrt)
}
headRef := dEnv.RepoStateReader().CWBHeadRef()
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return HandleVErrAndExitCode(errhand.BuildDError(err.Error()).Build(), nil)
}
ws, err := dEnv.WorkingSet(ctx)
if err != nil {
HandleVErrAndExitCode(errhand.BuildDError(err.Error()).Build(), usagePrt)
@@ -177,9 +180,14 @@ func checkoutNewBranch(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.Ar
return verr
}
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return errhand.BuildDError(err.Error()).Build()
}
// the new branch is checked out at this point
if setTrackUpstream {
verr = SetRemoteUpstreamForBranchRef(dEnv, remoteName, remoteBranchName, dEnv.RepoStateReader().CWBHeadRef())
verr = SetRemoteUpstreamForBranchRef(dEnv, remoteName, remoteBranchName, headRef)
if verr != nil {
return verr
}
@@ -195,7 +203,7 @@ func checkoutNewBranch(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.Ar
if !remoteOk {
return nil
}
verr = SetRemoteUpstreamForBranchRef(dEnv, remoteName, remoteBranchName, dEnv.RepoStateReader().CWBHeadRef())
verr = SetRemoteUpstreamForBranchRef(dEnv, remoteName, remoteBranchName, headRef)
if verr != nil {
return verr
}
@@ -230,7 +238,11 @@ func checkoutRemoteBranchOrSuggestNew(ctx context.Context, dEnv *env.DoltEnv, na
if verr != nil {
return verr
}
return SetRemoteUpstreamForBranchRef(dEnv, remoteRefs[0].GetRemote(), remoteRefs[0].GetBranch(), dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return errhand.BuildDError(err.Error()).Build()
}
return SetRemoteUpstreamForBranchRef(dEnv, remoteRefs[0].GetRemote(), remoteRefs[0].GetBranch(), headRef)
} else {
// TODO : add hint of using `dolt checkout --track <remote>/<branch>` when --track flag is supported
return errhand.BuildDError("'%s' matched multiple (%v) remote tracking branches", name, len(remoteRefs)).Build()
+5 -1
View File
@@ -183,7 +183,11 @@ func getCherryPickedRootValue(ctx context.Context, dEnv *env.DoltEnv, workingRoo
if err != nil {
return nil, "", err
}
cherryCm, err := dEnv.DoltDB.Resolve(ctx, cherrySpec, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil, "", err
}
cherryCm, err := dEnv.DoltDB.Resolve(ctx, cherrySpec, headRef)
if err != nil {
return nil, "", err
}
+9 -2
View File
@@ -221,9 +221,13 @@ func performCommit(ctx context.Context, commandStr string, args []string, dEnv *
return handleCommitErr(ctx, dEnv, err, usage)
}
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return handleCommitErr(ctx, dEnv, err, usage)
}
_, err = dEnv.DoltDB.CommitWithWorkingSet(
ctx,
dEnv.RepoStateReader().CWBHeadRef(),
headRef,
ws.Ref(),
pendingCommit,
ws.WithStagedRoot(pendingCommit.Roots.Staged).WithWorkingRoot(pendingCommit.Roots.Working).ClearMerge(),
@@ -381,7 +385,10 @@ func buildInitalCommitMsg(ctx context.Context, dEnv *env.DoltEnv, suggestedMsg s
return "", err
}
currBranch := dEnv.RepoStateReader().CWBHeadRef()
currBranch, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return "", err
}
initialCommitMessage := fmt.Sprintf("%s\n# Please enter the commit message for your changes. Lines starting"+
"\n# with '#' will be ignored, and an empty message aborts the commit."+
"\n# On branch %s\n#\n", suggestedMsg, currBranch)
+6 -1
View File
@@ -186,7 +186,12 @@ func getNerf(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResu
return nil, err
}
cm, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil, err
}
cm, err := dEnv.DoltDB.Resolve(ctx, cs, headRef)
if err != nil {
return nil, err
}
+21 -6
View File
@@ -123,7 +123,11 @@ func (cmd LogCmd) logWithLoggerFunc(ctx context.Context, commandStr string, args
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
if len(opts.commitSpecs) == 0 {
opts.commitSpecs = append(opts.commitSpecs, dEnv.RepoStateReader().CWBHeadSpec())
headRef, err := dEnv.RepoStateReader().CWBHeadSpec()
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
opts.commitSpecs = append(opts.commitSpecs, headRef)
}
if len(opts.tableName) > 0 {
return handleErrAndExit(logTableCommits(ctx, dEnv, opts))
@@ -245,7 +249,10 @@ func (opts *logOpts) parseRefsAndTable(ctx context.Context, apr *argparser.ArgPa
opts.excludingCommitSpecs = append(opts.excludingCommitSpecs, notCs)
} else {
argIsRef := actions.IsValidRef(ctx, arg, dEnv.DoltDB, dEnv.RepoStateReader())
argIsRef, err := actions.IsValidRef(ctx, arg, dEnv.DoltDB, dEnv.RepoStateReader())
if err != nil {
return nil
}
// <ref>
if argIsRef && !seenRefs[arg] {
cs, err := getCommitSpec(arg)
@@ -327,8 +334,12 @@ func getHashToRefs(ctx context.Context, dEnv *env.DoltEnv, decorationLevel strin
func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
hashes := make([]hash.Hash, len(opts.commitSpecs))
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return handleErrAndExit(err)
}
for i, cs := range opts.commitSpecs {
commit, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
commit, err := dEnv.DoltDB.Resolve(ctx, cs, headRef)
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: cannot get HEAD commit for current branch."))
return 1
@@ -360,7 +371,7 @@ func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
excludingHashes := make([]hash.Hash, len(opts.excludingCommitSpecs))
for i, excludingSpec := range opts.excludingCommitSpecs {
excludingCommit, err := dEnv.DoltDB.Resolve(ctx, excludingSpec, dEnv.RepoStateReader().CWBHeadRef())
excludingCommit, err := dEnv.DoltDB.Resolve(ctx, excludingSpec, headRef)
if err != nil {
cli.PrintErrln(color.HiRedString("Fatal error: cannot get excluding commit for current branch."))
return 1
@@ -383,7 +394,6 @@ func logCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) int {
return 1
}
headRef := dEnv.RepoStateReader().CWBHeadRef()
cwbHash, err := dEnv.DoltDB.GetHashForRefStr(ctx, headRef.String())
if err != nil {
@@ -441,8 +451,13 @@ func tableExists(ctx context.Context, commit *doltdb.Commit, tableName string) (
func logTableCommits(ctx context.Context, dEnv *env.DoltEnv, opts *logOpts) error {
hashes := make([]hash.Hash, len(opts.commitSpecs))
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
for i, cs := range opts.commitSpecs {
commit, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
commit, err := dEnv.DoltDB.Resolve(ctx, cs, headRef)
if err != nil {
return err
}
+6 -1
View File
@@ -121,7 +121,12 @@ func getRootForCommitSpecStr(ctx context.Context, csStr string, dEnv *env.DoltEn
return "", nil, bdr.AddCause(err).Build()
}
cm, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return "", nil, errhand.VerboseErrorFromError(err)
}
cm, err := dEnv.DoltDB.Resolve(ctx, cs, headRef)
if err != nil {
return "", nil, errhand.BuildDError(`Unable to resolve "%s"`, csStr).AddCause(err).Build()
+12 -2
View File
@@ -159,7 +159,12 @@ func (cmd MergeCmd) Exec(ctx context.Context, commandStr string, args []string,
return handleCommitErr(ctx, dEnv, err, usage)
}
suggestedMsg := fmt.Sprintf("Merge branch '%s' into %s", commitSpecStr, dEnv.RepoStateReader().CWBHeadRef().GetPath())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return handleCommitErr(ctx, dEnv, err, usage)
}
suggestedMsg := fmt.Sprintf("Merge branch '%s' into %s", commitSpecStr, headRef.GetPath())
msg := ""
if m, ok := apr.GetValue(cli.MessageArg); ok {
msg = m
@@ -529,10 +534,15 @@ func executeNoFFMergeAndCommit(ctx context.Context, dEnv *env.DoltEnv, spec *mer
Email: spec.Email,
})
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return tblToStats, err
}
wsHash, err := ws.HashOf()
_, err = dEnv.DoltDB.CommitWithWorkingSet(
ctx,
dEnv.RepoStateReader().CWBHeadRef(),
headRef,
ws.Ref(),
pendingCommit,
ws.WithStagedRoot(pendingCommit.Roots.Staged).WithWorkingRoot(pendingCommit.Roots.Working).ClearMerge(),
+6 -1
View File
@@ -119,7 +119,12 @@ func ResolveCommitWithVErr(dEnv *env.DoltEnv, cSpecStr string) (*doltdb.Commit,
return nil, errhand.BuildDError("'%s' is not a valid commit", cSpecStr).Build()
}
cm, err := dEnv.DoltDB.Resolve(context.TODO(), cs, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil, errhand.VerboseErrorFromError(err)
}
cm, err := dEnv.DoltDB.Resolve(context.TODO(), cs, headRef)
if err != nil {
if errors.Is(err, doltdb.ErrInvalidAncestorSpec) {
return nil, errhand.BuildDError("'%s' could not resolve ancestor spec", cSpecStr).Build()
+6 -1
View File
@@ -202,7 +202,12 @@ func pullHelper(ctx context.Context, dEnv *env.DoltEnv, pullSpec *env.PullSpec)
return err
}
suggestedMsg := fmt.Sprintf("Merge branch '%s' of %s into %s", pullSpec.Branch.GetPath(), pullSpec.Remote.Url, dEnv.RepoStateReader().CWBHeadRef().GetPath())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
suggestedMsg := fmt.Sprintf("Merge branch '%s' of %s into %s", pullSpec.Branch.GetPath(), pullSpec.Remote.Url, headRef.GetPath())
tblStats, err := performMerge(ctx, dEnv, mergeSpec, suggestedMsg)
printSuccessStats(tblStats)
if err != nil {
+13 -9
View File
@@ -96,16 +96,20 @@ func (cmd PushCmd) Exec(ctx context.Context, commandStr string, args []string, d
var verr errhand.VerboseError
switch err {
case env.ErrNoUpstreamForBranch:
currentBranch := dEnv.RepoStateReader().CWBHeadRef()
remoteName := "<remote>"
if defRemote, verr := env.GetDefaultRemote(dEnv.RepoStateReader()); verr == nil {
remoteName = defRemote.Name
currentBranch, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
verr = errhand.BuildDError("fatal: The current branch could not be identified").AddCause(err).Build()
} else {
remoteName := "<remote>"
if defRemote, verr := env.GetDefaultRemote(dEnv.RepoStateReader()); verr == nil {
remoteName = defRemote.Name
}
verr = errhand.BuildDError("fatal: The current branch " + currentBranch.GetPath() + " has no upstream branch.\n" +
"To push the current branch and set the remote as upstream, use\n" +
"\tdolt push --set-upstream " + remoteName + " " + currentBranch.GetPath() + "\n" +
"To have this happen automatically for branches without a tracking\n" +
"upstream, see 'push.autoSetupRemote' in 'dolt config --help'.").Build()
}
verr = errhand.BuildDError("fatal: The current branch " + currentBranch.GetPath() + " has no upstream branch.\n" +
"To push the current branch and set the remote as upstream, use\n" +
"\tdolt push --set-upstream " + remoteName + " " + currentBranch.GetPath() + "\n" +
"To have this happen automatically for branches without a tracking\n" +
"upstream, see 'push.autoSetupRemote' in 'dolt config --help'.").Build()
case env.ErrInvalidSetUpstreamArgs:
verr = errhand.BuildDError("error: --set-upstream requires <remote> and <refspec> params.").SetPrintUsage().Build()
+9 -2
View File
@@ -103,7 +103,11 @@ func (cmd ResetCmd) Exec(ctx context.Context, commandStr string, args []string,
} else {
if apr.NArg() == 1 {
ref := apr.Arg(0)
if actions.IsValidRef(ctx, ref, dEnv.DoltDB, dEnv.RepoStateReader()) {
isValidRef, err := actions.IsValidRef(ctx, ref, dEnv.DoltDB, dEnv.RepoStateReader())
if err != nil {
return handleErrAndExit(err)
}
if isValidRef {
return handleResetSoftToRef(ctx, dEnv, ref, usage)
}
}
@@ -145,7 +149,10 @@ func handleResetHard(ctx context.Context, apr *argparser.ArgParseResults, usage
arg = apr.Arg(0)
}
headRef := dEnv.RepoStateReader().CWBHeadRef()
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
ws, err := dEnv.WorkingSet(ctx)
if err != nil {
return HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
+15 -3
View File
@@ -159,7 +159,11 @@ func parseShowArgs(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPar
func showObjects(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts) error {
if len(opts.specRefs) == 0 {
return showCommitSpec(ctx, dEnv, opts, dEnv.RepoStateReader().CWBHeadSpec())
headRef, err := dEnv.RepoStateReader().CWBHeadSpec()
if err != nil {
return err
}
return showCommitSpec(ctx, dEnv, opts, headRef)
}
for _, specRef := range opts.specRefs {
@@ -243,7 +247,12 @@ func showSpecRef(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, specRef
func showCommitSpec(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, commitSpec *doltdb.CommitSpec) error {
commit, err := dEnv.DoltDB.Resolve(ctx, commitSpec, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
commit, err := dEnv.DoltDB.Resolve(ctx, commitSpec, headRef)
if err != nil {
return err
}
@@ -283,7 +292,10 @@ func showCommit(ctx context.Context, dEnv *env.DoltEnv, opts *showOpts, comm *do
return err
}
headRef := dEnv.RepoStateReader().CWBHeadRef()
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
cwbHash, err := dEnv.DoltDB.GetHashForRefStr(ctx, headRef.String())
if err != nil {
return err
+5 -1
View File
@@ -133,7 +133,11 @@ func applyStashAtIdx(ctx context.Context, dEnv *env.DoltEnv, curWorkingRoot *dol
if err != nil {
return false, err
}
parentCommit, err := dEnv.DoltDB.Resolve(ctx, headCommitSpec, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return false, err
}
parentCommit, err := dEnv.DoltDB.Resolve(ctx, headCommitSpec, headRef)
if err != nil {
return false, err
}
+4 -1
View File
@@ -224,7 +224,10 @@ func stashChanges(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgPars
}
}
curHeadRef := dEnv.RepoStateReader().CWBHeadRef()
curHeadRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
curBranchName := curHeadRef.String()
commitSpec, err := doltdb.NewCommitSpec(curBranchName)
if err != nil {
+11 -3
View File
@@ -95,9 +95,14 @@ func (cmd StatusCmd) Exec(ctx context.Context, commandStr string, args []string,
}
func PrintStatus(ctx context.Context, dEnv *env.DoltEnv, stagedTbls, notStagedTbls []diff.TableDelta, showIgnoredTables bool, as merge.ArtifactStatus) error {
cli.Printf(branchHeader, dEnv.RepoStateReader().CWBHeadRef().GetPath())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
err := printRemoteRefTrackingInfo(ctx, dEnv)
cli.Printf(branchHeader, headRef.GetPath())
err = printRemoteRefTrackingInfo(ctx, dEnv)
if err != nil {
return err
}
@@ -141,7 +146,10 @@ func handleStatusVErr(err error) int {
func printRemoteRefTrackingInfo(ctx context.Context, dEnv *env.DoltEnv) error {
ddb := dEnv.DoltDB
rsr := dEnv.RepoStateReader()
headRef := rsr.CWBHeadRef()
headRef, err := rsr.CWBHeadRef()
if err != nil {
return err
}
branches, err := rsr.GetBranches()
if err != nil {
return err
+5 -1
View File
@@ -219,7 +219,11 @@ func MaybeResolveRoot(ctx context.Context, rsr env.RepoStateReader, doltDB *dolt
return nil, false
}
cm, err := doltDB.Resolve(ctx, cs, rsr.CWBHeadRef())
headRef, err := rsr.CWBHeadRef()
if err != nil {
return nil, false
}
cm, err := doltDB.Resolve(ctx, cs, headRef)
if err != nil {
return nil, false
}
+2 -1
View File
@@ -29,7 +29,6 @@ var ErrInvalidBranchOrHash = errors.New("string is not a valid branch or hash")
var ErrInvalidHash = errors.New("string is not a valid hash")
var ErrFoundHashNotACommit = errors.New("the value retrieved for this hash is not a commit")
var ErrHashNotFound = errors.New("could not find a value for this hash")
var ErrBranchNotFound = errors.New("branch not found")
var ErrTagNotFound = errors.New("tag not found")
@@ -49,6 +48,8 @@ var ErrIsBehind = errors.New("cannot reverse from b to a. b is a is behind a alr
var ErrUnresolvedConflictsOrViolations = errors.New("merge has unresolved conflicts or constraint violations")
var ErrMergeActive = errors.New("merging is not possible because you have not committed an active merge")
var ErrOperationNotSupportedInDetachedHead = errors.New("this operation is not supported while in a detached head state")
type ErrClientOutOfDate struct {
RepoVer FeatureVersion
ClientVer FeatureVersion
@@ -260,9 +260,14 @@ func (mr *MultiRepoTestSetup) CommitWithWorkingSet(dbName string) *doltdb.Commit
panic("pending commit error: " + err.Error())
}
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
panic("couldn't get working set: " + err.Error())
}
commit, err := dEnv.DoltDB.CommitWithWorkingSet(
ctx,
dEnv.RepoStateReader().CWBHeadRef(),
headRef,
ws.Ref(),
pendingCommit,
ws.WithStagedRoot(pendingCommit.Roots.Staged).WithWorkingRoot(pendingCommit.Roots.Working).ClearMerge(),
+25 -5
View File
@@ -42,7 +42,11 @@ func RenameBranch(ctx context.Context, dbData env.DbData, oldBranch, newBranch s
return err
}
if ref.Equals(dbData.Rsr.CWBHeadRef(), oldRef) {
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return err
}
if ref.Equals(headRef, oldRef) {
err = dbData.Rsw.SetCWBHeadRef(ctx, ref.MarshalableRef{Ref: newRef})
if err != nil {
return err
@@ -124,7 +128,11 @@ func DeleteBranch(ctx context.Context, dbData env.DbData, brName string, opts De
}
} else {
branchRef = ref.NewBranchRef(brName)
if ref.Equals(dbData.Rsr.CWBHeadRef(), branchRef) {
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return err
}
if ref.Equals(headRef, branchRef) {
return ErrCOBranchDelete
}
}
@@ -195,7 +203,11 @@ func validateBranchMergedIntoCurrentWorkingBranch(ctx context.Context, dbdata en
return err
}
cwbHead, err := dbdata.Ddb.Resolve(ctx, cwbCs, dbdata.Rsr.CWBHeadRef())
headRef, err := dbdata.Rsr.CWBHeadRef()
if err != nil {
return err
}
cwbHead, err := dbdata.Ddb.Resolve(ctx, cwbCs, headRef)
if err != nil {
return err
}
@@ -325,7 +337,11 @@ func CreateBranchOnDB(ctx context.Context, ddb *doltdb.DoltDB, newBranch, starti
}
func createBranch(ctx context.Context, dbData env.DbData, newBranch, startingPoint string, force bool, rsc *doltdb.ReplicationStatusController) error {
return CreateBranchOnDB(ctx, dbData.Ddb, newBranch, startingPoint, force, dbData.Rsr.CWBHeadRef(), rsc)
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return err
}
return CreateBranchOnDB(ctx, dbData.Ddb, newBranch, startingPoint, force, headRef, rsc)
}
var emptyHash = hash.Hash{}
@@ -343,7 +359,11 @@ func MaybeGetCommit(ctx context.Context, dEnv *env.DoltEnv, str string) (*doltdb
cs, err := doltdb.NewCommitSpec(str)
if err == nil {
cm, err := dEnv.DoltDB.Resolve(ctx, cs, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil, err
}
cm, err := dEnv.DoltDB.Resolve(ctx, cs, headRef)
if errors.Is(err, doltdb.ErrBranchNotFound) {
return nil, nil
+9 -2
View File
@@ -159,7 +159,10 @@ func rootsForBranch(ctx context.Context, roots doltdb.Roots, branchRoot *doltdb.
func CheckoutBranch(ctx context.Context, dEnv *env.DoltEnv, brName string, force bool) error {
branchRef := ref.NewBranchRef(brName)
initialHeadRef := dEnv.RepoStateReader().CWBHeadRef()
initialHeadRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
db := dEnv.DoltDB
hasRef, err := db.HasRef(ctx, branchRef)
@@ -170,7 +173,11 @@ func CheckoutBranch(ctx context.Context, dEnv *env.DoltEnv, brName string, force
return doltdb.ErrBranchNotFound
}
if ref.Equals(dEnv.RepoStateReader().CWBHeadRef(), branchRef) {
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
if ref.Equals(headRef, branchRef) {
return doltdb.ErrAlreadyOnBranch
}
+5 -1
View File
@@ -168,7 +168,11 @@ func PushToRemoteBranch(ctx context.Context, rsr env.RepoStateReader, tempTableD
}
cs, _ := doltdb.NewCommitSpec(srcRef.GetPath())
cm, err := localDB.Resolve(ctx, cs, rsr.CWBHeadRef())
headRef, err := rsr.CWBHeadRef()
if err != nil {
return err
}
cm, err := localDB.Resolve(ctx, cs, headRef)
if err != nil {
return fmt.Errorf("%w; refspec not found: '%s'; %s", ref.ErrInvalidRefSpec, srcRef.GetPath(), err.Error())
+29 -9
View File
@@ -39,7 +39,11 @@ func resetHardTables(ctx context.Context, dbData env.DbData, cSpecStr string, ro
return nil, doltdb.Roots{}, err
}
newHead, err = ddb.Resolve(ctx, cs, rsr.CWBHeadRef())
headRef, err := rsr.CWBHeadRef()
if err != nil {
return nil, doltdb.Roots{}, err
}
newHead, err = ddb.Resolve(ctx, cs, headRef)
if err != nil {
return nil, doltdb.Roots{}, err
}
@@ -220,7 +224,11 @@ func ResetSoftToRef(ctx context.Context, dbData env.DbData, cSpecStr string) (do
return doltdb.Roots{}, err
}
newHead, err := dbData.Ddb.Resolve(ctx, cs, dbData.Rsr.CWBHeadRef())
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return doltdb.Roots{}, err
}
newHead, err := dbData.Ddb.Resolve(ctx, cs, headRef)
if err != nil {
return doltdb.Roots{}, err
}
@@ -231,7 +239,7 @@ func ResetSoftToRef(ctx context.Context, dbData env.DbData, cSpecStr string) (do
}
// Update the head to this commit
if err = dbData.Ddb.SetHeadToCommit(ctx, dbData.Rsr.CWBHeadRef(), newHead); err != nil {
if err = dbData.Ddb.SetHeadToCommit(ctx, headRef, newHead); err != nil {
return doltdb.Roots{}, err
}
@@ -265,19 +273,31 @@ func resetStaged(ctx context.Context, roots doltdb.Roots, tbls []string) (doltdb
}
// IsValidRef validates whether the input parameter is a valid cString
// TODO: this doesn't belong int his package
func IsValidRef(ctx context.Context, cSpecStr string, ddb *doltdb.DoltDB, rsr env.RepoStateReader) bool {
// TODO: this doesn't belong in this package
func IsValidRef(ctx context.Context, cSpecStr string, ddb *doltdb.DoltDB, rsr env.RepoStateReader) (bool, error) {
// The error return value is only for propagating unhandled errors from rsr.CWBHeadRef()
// All other errors merely indicate an invalid ref spec.
// TODO: It's much better to enumerate the expected errors, to make sure we don't suppress any unexpected ones.
cs, err := doltdb.NewCommitSpec(cSpecStr)
if err != nil {
return false
return false, nil
}
_, err = ddb.Resolve(ctx, cs, rsr.CWBHeadRef())
headRef, err := rsr.CWBHeadRef()
if err == doltdb.ErrOperationNotSupportedInDetachedHead {
// This is safe because ddb.Resolve checks if headRef is nil, but only when the value is actually needed.
// Basically, this guarentees that resolving "HEAD" or similar will return an error but other resolves will work.
headRef = nil
} else if err != nil {
return false, err
}
_, err = ddb.Resolve(ctx, cs, headRef)
if err != nil {
return false
return false, nil
}
return true
return true, nil
}
// CleanUntracked deletes untracked tables from the working root.
+5 -1
View File
@@ -32,7 +32,11 @@ type TagProps struct {
}
func CreateTag(ctx context.Context, dEnv *env.DoltEnv, tagName, startPoint string, props TagProps) error {
return CreateTagOnDB(ctx, dEnv.DoltDB, tagName, startPoint, props, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
return CreateTagOnDB(ctx, dEnv.DoltDB, tagName, startPoint, props, headRef)
}
func CreateTagOnDB(ctx context.Context, ddb *doltdb.DoltDB, tagName, startPoint string, props TagProps, headRef ref.DoltRef) error {
+10 -2
View File
@@ -28,7 +28,11 @@ var ErrCOWorkspaceDelete = errors.New("attempted to delete checked out workspace
var ErrBranchNameExists = errors.New("workspace name must not be existing branch name")
func CreateWorkspace(ctx context.Context, dEnv *env.DoltEnv, name, startPoint string) error {
return CreateWorkspaceOnDB(ctx, dEnv.DoltDB, name, startPoint, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil
}
return CreateWorkspaceOnDB(ctx, dEnv.DoltDB, name, startPoint, headRef)
}
func CreateWorkspaceOnDB(ctx context.Context, ddb *doltdb.DoltDB, name, startPoint string, headRef ref.DoltRef) error {
@@ -86,7 +90,11 @@ func DeleteWorkspace(ctx context.Context, dEnv *env.DoltEnv, workspaceName strin
}
} else {
dref = ref.NewWorkspaceRef(workspaceName)
if ref.Equals(dEnv.RepoStateReader().CWBHeadRef(), dref) {
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
if ref.Equals(headRef, dref) {
return ErrCOWorkspaceDelete
}
}
+13 -6
View File
@@ -206,7 +206,10 @@ func (dEnv *DoltEnv) Valid() bool {
// initWorkingSetFromRepoState sets the working set for the env's head to mirror the contents of the repo state file.
// This is only necessary to migrate repos written before this method was introduced, and can be removed after 1.0
func (dEnv *DoltEnv) initWorkingSetFromRepoState(ctx context.Context) error {
headRef := dEnv.RepoStateReader().CWBHeadRef()
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
wsRef, err := ref.WorkingSetRefForHead(headRef)
if err != nil {
return err
@@ -591,7 +594,11 @@ func (dEnv *DoltEnv) WorkingSet(ctx context.Context) (*doltdb.WorkingSet, error)
}
func WorkingSet(ctx context.Context, ddb *doltdb.DoltDB, rsr RepoStateReader) (*doltdb.WorkingSet, error) {
workingSetRef, err := ref.WorkingSetRefForHead(rsr.CWBHeadRef())
headRef, err := rsr.CWBHeadRef()
if err != nil {
return nil, err
}
workingSetRef, err := ref.WorkingSetRefForHead(headRef)
if err != nil {
return nil, err
}
@@ -655,12 +662,12 @@ type repoStateReader struct {
*DoltEnv
}
func (r *repoStateReader) CWBHeadRef() ref.DoltRef {
return r.RepoState.CWBHeadRef()
func (r *repoStateReader) CWBHeadRef() (ref.DoltRef, error) {
return r.RepoState.CWBHeadRef(), nil
}
func (r *repoStateReader) CWBHeadSpec() *doltdb.CommitSpec {
return r.RepoState.CWBHeadSpec()
func (r *repoStateReader) CWBHeadSpec() (*doltdb.CommitSpec, error) {
return r.RepoState.CWBHeadSpec(), nil
}
func (dEnv *DoltEnv) RepoStateReader() RepoStateReader {
+25 -9
View File
@@ -101,16 +101,20 @@ type MemoryRepoState struct {
var _ RepoStateReader = MemoryRepoState{}
var _ RepoStateWriter = MemoryRepoState{}
func (m MemoryRepoState) CWBHeadRef() ref.DoltRef {
return m.Head
func (m MemoryRepoState) CWBHeadRef() (ref.DoltRef, error) {
return m.Head, nil
}
func (m MemoryRepoState) CWBHeadSpec() *doltdb.CommitSpec {
spec, err := doltdb.NewCommitSpec(m.CWBHeadRef().GetPath())
func (m MemoryRepoState) CWBHeadSpec() (*doltdb.CommitSpec, error) {
headRef, err := m.CWBHeadRef()
if err != nil {
panic(err)
return nil, err
}
return spec
spec, err := doltdb.NewCommitSpec(headRef.GetPath())
if err != nil {
return nil, err
}
return spec, nil
}
func (m MemoryRepoState) UpdateStagedRoot(ctx context.Context, newRoot *doltdb.RootValue) error {
@@ -120,7 +124,11 @@ func (m MemoryRepoState) UpdateStagedRoot(ctx context.Context, newRoot *doltdb.R
ws, err := m.WorkingSet(ctx)
if err == doltdb.ErrWorkingSetNotFound {
// first time updating root
wsRef, err = ref.WorkingSetRefForHead(m.CWBHeadRef())
headRef, err := m.CWBHeadRef()
if err != nil {
return err
}
wsRef, err = ref.WorkingSetRefForHead(headRef)
if err != nil {
return err
}
@@ -146,7 +154,11 @@ func (m MemoryRepoState) UpdateWorkingRoot(ctx context.Context, newRoot *doltdb.
ws, err := m.WorkingSet(ctx)
if err == doltdb.ErrWorkingSetNotFound {
// first time updating root
wsRef, err = ref.WorkingSetRefForHead(m.CWBHeadRef())
headRef, err := m.CWBHeadRef()
if err != nil {
return err
}
wsRef, err = ref.WorkingSetRefForHead(headRef)
if err != nil {
return err
}
@@ -166,7 +178,11 @@ func (m MemoryRepoState) UpdateWorkingRoot(ctx context.Context, newRoot *doltdb.
}
func (m MemoryRepoState) WorkingSet(ctx context.Context) (*doltdb.WorkingSet, error) {
workingSetRef, err := ref.WorkingSetRefForHead(m.CWBHeadRef())
headRef, err := m.CWBHeadRef()
if err != nil {
return nil, err
}
workingSetRef, err := ref.WorkingSetRefForHead(headRef)
if err != nil {
return nil, err
}
+8 -2
View File
@@ -141,7 +141,10 @@ func NewPushOpts(ctx context.Context, apr *argparser.ArgParseResults, rsr RepoSt
}
remote, remoteOK := remotes[remoteName]
currentBranch := rsr.CWBHeadRef()
currentBranch, err := rsr.CWBHeadRef()
if err != nil {
return nil, err
}
branches, err := rsr.GetBranches()
if err != nil {
return nil, err
@@ -422,7 +425,10 @@ func NewPullSpec(_ context.Context, rsr RepoStateReader, remoteName, remoteRefNa
var remoteRef ref.DoltRef
if remoteRefName == "" {
branch := rsr.CWBHeadRef()
branch, err := rsr.CWBHeadRef()
if err != nil {
return nil, err
}
trackedBranches, err := rsr.GetBranches()
if err != nil {
return nil, err
+2 -2
View File
@@ -27,8 +27,8 @@ import (
// TODO: change name to ClientStateReader, move out of env package
type RepoStateReader interface {
CWBHeadRef() ref.DoltRef
CWBHeadSpec() *doltdb.CommitSpec
CWBHeadRef() (ref.DoltRef, error)
CWBHeadSpec() (*doltdb.CommitSpec, error)
GetRemotes() (map[string]Remote, error)
GetBackups() (map[string]Remote, error)
GetBranches() (map[string]BranchConfig, error)
+12 -3
View File
@@ -62,7 +62,12 @@ func NewMergeSpec(ctx context.Context, rsr env.RepoStateReader, ddb *doltdb.Dolt
return nil, err
}
headCM, err := ddb.Resolve(context.TODO(), headCS, rsr.CWBHeadRef())
headRef, err := rsr.CWBHeadRef()
if err != nil {
return nil, err
}
headCM, err := ddb.Resolve(context.TODO(), headCS, headRef)
if err != nil {
return nil, err
}
@@ -72,7 +77,7 @@ func NewMergeSpec(ctx context.Context, rsr env.RepoStateReader, ddb *doltdb.Dolt
return nil, err
}
mergeCM, err := ddb.Resolve(context.TODO(), mergeCS, rsr.CWBHeadRef())
mergeCM, err := ddb.Resolve(context.TODO(), mergeCS, headRef)
if err != nil {
return nil, err
}
@@ -159,7 +164,11 @@ func ExecuteFFMerge(
}
if !spec.Squash {
err = dEnv.DoltDB.FastForward(ctx, dEnv.RepoStateReader().CWBHeadRef(), spec.MergeC)
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return err
}
err = dEnv.DoltDB.FastForward(ctx, headRef, spec.MergeC)
if err != nil {
return err
+10 -2
View File
@@ -113,7 +113,11 @@ func AllBranches(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn,
// CurrentBranch rewrites the history of the current branch using the |replay| function.
func CurrentBranch(ctx context.Context, dEnv *env.DoltEnv, replay ReplayCommitFn, nerf NeedsRebaseFn) error {
return rebaseRefs(ctx, dEnv.DbData(), replay, nerf, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil
}
return rebaseRefs(ctx, dEnv.DbData(), replay, nerf, headRef)
}
// AllBranchesByRoots rewrites the history of all branches in the repo using the |replay| function.
@@ -130,7 +134,11 @@ func AllBranchesByRoots(ctx context.Context, dEnv *env.DoltEnv, replay ReplayRoo
// CurrentBranchByRoot rewrites the history of the current branch using the |replay| function.
func CurrentBranchByRoot(ctx context.Context, dEnv *env.DoltEnv, replay ReplayRootFn, nerf NeedsRebaseFn) error {
replayCommit := wrapReplayRootFn(replay)
return rebaseRefs(ctx, dEnv.DbData(), replayCommit, nerf, dEnv.RepoStateReader().CWBHeadRef())
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return nil
}
return rebaseRefs(ctx, dEnv.DbData(), replayCommit, nerf, headRef)
}
func rebaseRefs(ctx context.Context, dbData env.DbData, replay ReplayCommitFn, nerf NeedsRebaseFn, refs ...ref.DoltRef) error {
+14 -2
View File
@@ -417,14 +417,17 @@ func (db Database) getTableInsensitive(ctx *sql.Context, head *doltdb.Commit, ds
// resolveAsOf resolves given expression to a commit, if one exists.
func resolveAsOf(ctx *sql.Context, db Database, asOf interface{}) (*doltdb.Commit, *doltdb.RootValue, error) {
head := db.rsr.CWBHeadRef()
head, err := db.rsr.CWBHeadRef()
if err != nil {
return nil, nil, err
}
switch x := asOf.(type) {
case time.Time:
return resolveAsOfTime(ctx, db.ddb, head, x)
case string:
return resolveAsOfCommitRef(ctx, db, head, x)
default:
panic(fmt.Sprintf("unsupported AS OF type %T", asOf))
return nil, nil, fmt.Errorf("unsupported AS OF type %T", asOf)
}
}
@@ -645,6 +648,12 @@ func (db Database) GetRoot(ctx *sql.Context) (*doltdb.RootValue, error) {
return dbState.GetRoots().Working, nil
}
// GetWorkingSet gets the current working set for the database.
// If there is no working set (most likely because the DB is in Detached Head mode, return an error.
// If a command needs to work while in Detached Head, that command should call sess.LookupDbState directly.
// TODO: This is a temporary measure to make sure that new commands that call GetWorkingSet don't unexpectedly receive
// a null pointer. In the future, we should replace all uses of dbState.WorkingSet, including this, with a new interface
// where users avoid handling the WorkingSet directly.
func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) {
sess := dsess.DSessFromSess(ctx.Session)
dbState, ok, err := sess.LookupDbState(ctx, db.Name())
@@ -654,6 +663,9 @@ func (db Database) GetWorkingSet(ctx *sql.Context) (*doltdb.WorkingSet, error) {
if !ok {
return nil, fmt.Errorf("no root value found in session")
}
if dbState.WorkingSet == nil {
return nil, doltdb.ErrOperationNotSupportedInDetachedHead
}
return dbState.WorkingSet, nil
}
@@ -864,7 +864,11 @@ func initialDbState(ctx context.Context, db dsess.SqlDatabase, branch string) (d
if len(branch) > 0 {
r = ref.NewBranchRef(branch)
} else {
r = rsr.CWBHeadRef()
var err error
r, err = rsr.CWBHeadRef()
if err != nil {
return dsess.InitialDbState{}, err
}
}
var retainedErr error
@@ -1418,7 +1422,11 @@ func initialStateForCommit(ctx context.Context, srcDb ReadOnlyDatabase) (dsess.I
return dsess.InitialDbState{}, err
}
cm, err := srcDb.DbData().Ddb.Resolve(ctx, spec, srcDb.DbData().Rsr.CWBHeadRef())
headRef, err := srcDb.DbData().Rsr.CWBHeadRef()
if err != nil {
return dsess.InitialDbState{}, err
}
cm, err := srcDb.DbData().Ddb.Resolve(ctx, spec, headRef)
if err != nil {
return dsess.InitialDbState{}, err
}
@@ -1448,8 +1456,8 @@ type staticRepoState struct {
env.RepoStateReader
}
func (s staticRepoState) CWBHeadRef() ref.DoltRef {
return s.branch
func (s staticRepoState) CWBHeadRef() (ref.DoltRef, error) {
return s.branch, nil
}
// formatDbMapKeyName returns formatted string of database name and/or branch name. Database name is case-insensitive,
@@ -20,6 +20,7 @@ import (
"github.com/dolthub/go-mysql-server/sql"
"github.com/dolthub/go-mysql-server/sql/types"
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
"github.com/dolthub/dolt/go/libraries/doltcore/sqle/dsess"
)
@@ -46,6 +47,10 @@ func (ab *ActiveBranchFunc) Eval(ctx *sql.Context, row sql.Row) (interface{}, er
}
currentBranchRef, err := dSess.CWBHeadRef(ctx, dbName)
if err == doltdb.ErrOperationNotSupportedInDetachedHead {
// active_branch should return NULL if we're in detached head state
return nil, nil
}
if err != nil {
return nil, err
}
@@ -94,11 +94,16 @@ func resolveRefSpecs(ctx *sql.Context, leftSpec, rightSpec string) (left, right
return nil, nil, sql.ErrDatabaseNotFound.New(dbName)
}
left, err = doltDB.Resolve(ctx, lcs, dbData.Rsr.CWBHeadRef())
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return nil, nil, err
}
right, err = doltDB.Resolve(ctx, rcs, dbData.Rsr.CWBHeadRef())
left, err = doltDB.Resolve(ctx, lcs, headRef)
if err != nil {
return nil, nil, err
}
right, err = doltDB.Resolve(ctx, rcs, headRef)
if err != nil {
return nil, nil, err
}
@@ -224,7 +224,12 @@ func checkoutRemoteBranch(ctx *sql.Context, dbName string, dbData env.DbData, br
return errhand.BuildDError(fmt.Errorf("%w: '%s'", err, remoteRef.GetRemote()).Error()).Build()
}
return env.SetRemoteUpstreamForRefSpec(dbData.Rsw, refSpec, remoteRef.GetRemote(), dbData.Rsr.CWBHeadRef())
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return err
}
return env.SetRemoteUpstreamForRefSpec(dbData.Rsw, refSpec, remoteRef.GetRemote(), headRef)
} else {
return fmt.Errorf("'%s' matched multiple (%v) remote tracking branches", branchName, len(remoteRefs))
}
@@ -136,7 +136,11 @@ func cherryPick(ctx *sql.Context, dSess *dsess.DoltSession, roots doltdb.Roots,
if err != nil {
return nil, "", err
}
cherryCommit, err := doltDB.Resolve(ctx, cherryCommitSpec, dbData.Rsr.CWBHeadRef())
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return nil, "", err
}
cherryCommit, err := doltDB.Resolve(ctx, cherryCommitSpec, headRef)
if err != nil {
return nil, "", err
}
@@ -120,7 +120,12 @@ func doDoltMerge(ctx *sql.Context, args []string) (int, int, error) {
if !ok {
return noConflictsOrViolations, threeWayMerge, fmt.Errorf("Could not load database %s", dbName)
}
msg := fmt.Sprintf("Merge branch '%s' into %s", branchName, dbData.Rsr.CWBHeadRef().GetPath())
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return noConflictsOrViolations, threeWayMerge, err
}
msg := fmt.Sprintf("Merge branch '%s' into %s", branchName, headRef.GetPath())
if userMsg, mOk := apr.GetValue(cli.MessageArg); mOk {
msg = userMsg
}
@@ -266,7 +271,11 @@ func executeFFMerge(ctx *sql.Context, dbName string, squash bool, ws *doltdb.Wor
// TODO: This is all incredibly suspect, needs to be replaced with library code that is functional instead of
// altering global state
if !squash {
err = dbData.Ddb.FastForward(ctx, dbData.Rsr.CWBHeadRef(), cm2)
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return nil, err
}
err = dbData.Ddb.FastForward(ctx, headRef, cm2)
if err != nil {
return ws, err
}
@@ -148,7 +148,11 @@ func doDoltPull(ctx *sql.Context, args []string) (int, int, error) {
return noConflictsOrViolations, threeWayMerge, err
}
msg := fmt.Sprintf("Merge branch '%s' of %s into %s", pullSpec.Branch.GetPath(), pullSpec.Remote.Url, dbData.Rsr.CWBHeadRef().GetPath())
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return noConflictsOrViolations, threeWayMerge, err
}
msg := fmt.Sprintf("Merge branch '%s' of %s into %s", pullSpec.Branch.GetPath(), pullSpec.Remote.Url, headRef.GetPath())
ws, conflicts, fastForward, err = performMerge(ctx, sess, roots, ws, dbName, mergeSpec, apr.Contains(cli.NoCommitFlag), msg)
if err != nil && !errors.Is(doltdb.ErrUpToDate, err) {
return conflicts, fastForward, err
@@ -100,7 +100,11 @@ func doDoltReset(ctx *sql.Context, args []string) (int, error) {
// TODO: this overrides the transaction setting, needs to happen at commit, not here
if newHead != nil {
if err := dbData.Ddb.SetHeadToCommit(ctx, dbData.Rsr.CWBHeadRef(), newHead); err != nil {
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return 1, err
}
if err := dbData.Ddb.SetHeadToCommit(ctx, headRef, newHead); err != nil {
return 1, err
}
}
@@ -97,7 +97,10 @@ func doDoltTag(ctx *sql.Context, args []string) (int, error) {
if len(apr.Args) > 1 {
startPoint = apr.Arg(1)
}
headRef := dbData.Rsr.CWBHeadRef()
headRef, err := dbData.Rsr.CWBHeadRef()
if err != nil {
return 0, err
}
err = actions.CreateTagOnDB(ctx, dbData.Ddb, tagName, startPoint, props, headRef)
if err != nil {
return 1, err
+13 -2
View File
@@ -573,7 +573,7 @@ func (d *DoltSession) NewPendingCommit(ctx *sql.Context, dbName string, roots do
headHash, _ := headCommit.HashOf()
if sessionState.WorkingSet == nil {
return nil, fmt.Errorf("Cannot commit while not attached to a branch. ")
return nil, doltdb.ErrOperationNotSupportedInDetachedHead
}
var mergeParentCommits []*doltdb.Commit
@@ -841,6 +841,10 @@ func (d *DoltSession) SetRoot(ctx *sql.Context, dbName string, newRoot *doltdb.R
return err
}
if sessionState.WorkingSet == nil {
return doltdb.ErrOperationNotSupportedInDetachedHead
}
if rootsEqual(sessionState.GetRoots().Working, newRoot) {
return nil
}
@@ -864,6 +868,10 @@ func (d *DoltSession) SetRoots(ctx *sql.Context, dbName string, roots doltdb.Roo
return err
}
if sessionState.WorkingSet == nil {
return doltdb.ErrOperationNotSupportedInDetachedHead
}
workingSet := sessionState.WorkingSet.WithWorkingRoot(roots.Working).WithStagedRoot(roots.Staged)
return d.SetWorkingSet(ctx, dbName, workingSet)
}
@@ -1039,6 +1047,9 @@ func (d *DoltSession) WorkingSet(ctx *sql.Context, dbName string) (*doltdb.Worki
if err != nil {
return nil, err
}
if sessionState.WorkingSet == nil {
return nil, doltdb.ErrOperationNotSupportedInDetachedHead
}
return sessionState.WorkingSet, nil
}
@@ -1266,7 +1277,7 @@ func (d *DoltSession) CWBHeadRef(ctx *sql.Context, dbName string) (ref.DoltRef,
}
if dbState.WorkingSet == nil {
return nil, nil
return nil, doltdb.ErrOperationNotSupportedInDetachedHead
}
return dbState.WorkingSet.Ref().ToHeadRef()
@@ -61,29 +61,30 @@ func (s SessionStateAdapter) GetRoots(ctx context.Context) (doltdb.Roots, error)
return state.GetRoots(), nil
}
func (s SessionStateAdapter) CWBHeadRef() ref.DoltRef {
func (s SessionStateAdapter) CWBHeadRef() (ref.DoltRef, error) {
workingSet, err := s.session.WorkingSet(sql.NewContext(context.Background()), s.dbName)
if err != nil {
// TODO: fix this interface
panic(err)
return nil, err
}
headRef, err := workingSet.Ref().ToHeadRef()
// TODO: fix this interface
if err != nil {
panic(err)
return nil, err
}
return headRef
return headRef, nil
}
func (s SessionStateAdapter) CWBHeadSpec() *doltdb.CommitSpec {
func (s SessionStateAdapter) CWBHeadSpec() (*doltdb.CommitSpec, error) {
// TODO: get rid of this
ref := s.CWBHeadRef()
ref, err := s.CWBHeadRef()
if err != nil {
return nil, err
}
spec, err := doltdb.NewCommitSpec(ref.GetPath())
if err != nil {
panic(err)
}
return spec
return spec, nil
}
func (s SessionStateAdapter) GetRemotes() (map[string]env.Remote, error) {
@@ -117,13 +117,12 @@ var _ sql.RowDeleter = (*ignoreWriter)(nil)
type ignoreWriter struct {
it *IgnoreTable
errDuringStatementBegin error
workingSet *doltdb.WorkingSet
prevHash *hash.Hash
tableWriter writer.TableWriter
}
func newIgnoreWriter(it *IgnoreTable) *ignoreWriter {
return &ignoreWriter{it, nil, nil, nil, nil}
return &ignoreWriter{it, nil, nil, nil}
}
// Insert inserts the row given, returning an error if it cannot. Insert will be called once for each row to process
@@ -179,7 +178,6 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) {
iw.prevHash = &prevHash
iw.workingSet = dbState.WorkingSet
found, err := roots.Working.HasTable(ctx, doltdb.IgnoreTableName)
if err != nil {
@@ -229,6 +227,11 @@ func (iw *ignoreWriter) StatementBegin(ctx *sql.Context) {
return
}
if dbState.WorkingSet == nil {
iw.errDuringStatementBegin = doltdb.ErrOperationNotSupportedInDetachedHead
return
}
// We use WriteSession.SetWorkingSet instead of DoltSession.SetRoot because we want to avoid modifying the root
// until the end of the transaction, but we still want the WriteSession to be able to find the newly
// created table.
@@ -169,11 +169,18 @@ func drainIter(ctx *sql.Context, iter sql.RowIter) error {
return iter.Close(ctx)
}
func getDbState(t *testing.T, db sql.Database, dEnv *env.DoltEnv) dsess.InitialDbState {
func getDbState(t *testing.T, db sql.Database, dEnv *env.DoltEnv) (dsess.InitialDbState, error) {
ctx := context.Background()
head := dEnv.RepoStateReader().CWBHeadSpec()
headCommit, err := dEnv.DoltDB.Resolve(ctx, head, dEnv.RepoStateReader().CWBHeadRef())
headSpec, err := dEnv.RepoStateReader().CWBHeadSpec()
if err != nil {
return dsess.InitialDbState{}, err
}
headRef, err := dEnv.RepoStateReader().CWBHeadRef()
if err != nil {
return dsess.InitialDbState{}, err
}
headCommit, err := dEnv.DoltDB.Resolve(ctx, headSpec, headRef)
require.NoError(t, err)
ws, err := dEnv.WorkingSet(ctx)
@@ -185,5 +192,5 @@ func getDbState(t *testing.T, db sql.Database, dEnv *env.DoltEnv) dsess.InitialD
WorkingSet: ws,
DbData: dEnv.DbData(),
Remotes: dEnv.RepoState.Remotes,
}
}, nil
}
+3
View File
@@ -1258,6 +1258,9 @@ func (t *AlterableDoltTable) RewriteInserter(
}
ws := dbState.WorkingSet
if ws == nil {
return nil, doltdb.ErrOperationNotSupportedInDetachedHead
}
head, err := sess.GetHeadCommit(ctx, t.db.Name())
if err != nil {
+6
View File
@@ -79,6 +79,9 @@ func NewTempTable(
}
ws := dbState.WorkingSet
if ws == nil {
return nil, doltdb.ErrOperationNotSupportedInDetachedHead
}
sch, err := temporaryDoltSchema(ctx, pkSch, collation)
if err != nil {
@@ -153,6 +156,9 @@ func setTempTableRoot(t *TempTable) func(ctx *sql.Context, dbName string, newRoo
}
ws := dbState.WorkingSet
if ws == nil {
return doltdb.ErrOperationNotSupportedInDetachedHead
}
newWs := ws.WithWorkingRoot(newRoot)
ait, err := globalstate.NewAutoIncrementTracker(ctx, newWs)