mirror of
https://github.com/dolthub/dolt.git
synced 2026-05-03 19:41:24 -05:00
Merge pull request #5165 from dolthub/zachmu/delete-branch
Fixed branch -d behavior on unmerged branches to match git
This commit is contained in:
@@ -72,6 +72,8 @@ const (
|
||||
showCurrentFlag = "show-current"
|
||||
)
|
||||
|
||||
var ErrUnmergedBranchDelete = errors.New("The branch '%s' is not fully merged.\nIf you are sure you want to delete it, run 'dolt branch -D %s'.")
|
||||
|
||||
type BranchCmd struct{}
|
||||
|
||||
// Name is returns the name of the Dolt cli command. This is what is used on the command line to invoke the command
|
||||
@@ -124,9 +126,9 @@ func (cmd BranchCmd) Exec(ctx context.Context, commandStr string, args []string,
|
||||
case apr.Contains(copyFlag):
|
||||
return copyBranch(ctx, dEnv, apr, usage)
|
||||
case apr.Contains(deleteFlag):
|
||||
return deleteBranches(ctx, dEnv, apr, usage)
|
||||
return deleteBranches(ctx, dEnv, apr, usage, apr.Contains(forceFlag))
|
||||
case apr.Contains(deleteForceFlag):
|
||||
return deleteForceBranches(ctx, dEnv, apr, usage)
|
||||
return deleteBranches(ctx, dEnv, apr, usage, true)
|
||||
case apr.Contains(listFlag):
|
||||
return printBranches(ctx, dEnv, apr, usage)
|
||||
case apr.Contains(showCurrentFlag):
|
||||
@@ -261,7 +263,7 @@ func moveBranch(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseR
|
||||
force := apr.Contains(forceFlag)
|
||||
src := apr.Arg(0)
|
||||
dest := apr.Arg(1)
|
||||
err := actions.RenameBranch(ctx, dEnv.DbData(), dEnv.Config, src, apr.Arg(1), force)
|
||||
err := actions.RenameBranch(ctx, dEnv.DbData(), src, apr.Arg(1), dEnv, force)
|
||||
|
||||
var verr errhand.VerboseError
|
||||
if err != nil {
|
||||
@@ -310,31 +312,26 @@ func copyBranch(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseR
|
||||
return HandleVErrAndExitCode(verr, usage)
|
||||
}
|
||||
|
||||
func deleteBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults, usage cli.UsagePrinter) int {
|
||||
return handleDeleteBranches(ctx, dEnv, apr, usage, apr.Contains(forceFlag))
|
||||
}
|
||||
|
||||
func deleteForceBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults, usage cli.UsagePrinter) int {
|
||||
return handleDeleteBranches(ctx, dEnv, apr, usage, true)
|
||||
}
|
||||
|
||||
func handleDeleteBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults, usage cli.UsagePrinter, force bool) int {
|
||||
func deleteBranches(ctx context.Context, dEnv *env.DoltEnv, apr *argparser.ArgParseResults, usage cli.UsagePrinter, force bool) int {
|
||||
if apr.NArg() == 0 {
|
||||
usage()
|
||||
return 1
|
||||
}
|
||||
|
||||
for i := 0; i < apr.NArg(); i++ {
|
||||
brName := apr.Arg(i)
|
||||
|
||||
err := actions.DeleteBranch(ctx, dEnv.DbData(), dEnv.Config, brName, actions.DeleteOptions{
|
||||
err := actions.DeleteBranch(ctx, dEnv.DbData(), brName, actions.DeleteOptions{
|
||||
Force: force,
|
||||
Remote: apr.Contains(remoteFlag),
|
||||
})
|
||||
}, dEnv)
|
||||
|
||||
if err != nil {
|
||||
var verr errhand.VerboseError
|
||||
if err == doltdb.ErrBranchNotFound {
|
||||
verr = errhand.BuildDError("fatal: branch '%s' not found", brName).Build()
|
||||
} else if err == actions.ErrUnmergedBranch {
|
||||
verr = errhand.BuildDError(ErrUnmergedBranchDelete.Error(), brName, brName).Build()
|
||||
} else if err == actions.ErrCOBranchDelete {
|
||||
verr = errhand.BuildDError("error: Cannot delete checked out branch '%s'", brName).Build()
|
||||
} else {
|
||||
|
||||
@@ -147,7 +147,7 @@ func pullHelper(ctx context.Context, dEnv *env.DoltEnv, pullSpec *env.PullSpec)
|
||||
return fmt.Errorf("fetch failed; %w", err)
|
||||
}
|
||||
|
||||
// Only merge iff branch is current branch and there is an upstream set (pullSpec.Branch is set to nil if there is no upstream)
|
||||
// Merge iff branch is current branch and there is an upstream set (pullSpec.Branch is set to nil if there is no upstream)
|
||||
if branchRef != pullSpec.Branch {
|
||||
continue
|
||||
}
|
||||
|
||||
+118
-36
@@ -29,10 +29,10 @@ import (
|
||||
|
||||
var ErrAlreadyExists = errors.New("already exists")
|
||||
var ErrCOBranchDelete = errors.New("attempted to delete checked out branch")
|
||||
var ErrUnmergedBranchDelete = errors.New("attempted to delete a branch that is not fully merged into its parent; use `-f` to force")
|
||||
var ErrUnmergedBranch = errors.New("branch is not fully merged")
|
||||
var ErrWorkingSetsOnBothBranches = errors.New("checkout would overwrite uncommitted changes on target branch")
|
||||
|
||||
func RenameBranch(ctx context.Context, dbData env.DbData, config *env.DoltCliConfig, oldBranch, newBranch string, force bool) error {
|
||||
func RenameBranch(ctx context.Context, dbData env.DbData, oldBranch, newBranch string, remoteDbPro env.RemoteDbProvider, force bool) error {
|
||||
oldRef := ref.NewBranchRef(oldBranch)
|
||||
newRef := ref.NewBranchRef(newBranch)
|
||||
|
||||
@@ -67,7 +67,7 @@ func RenameBranch(ctx context.Context, dbData env.DbData, config *env.DoltCliCon
|
||||
}
|
||||
}
|
||||
|
||||
return DeleteBranch(ctx, dbData, config, oldBranch, DeleteOptions{Force: true})
|
||||
return DeleteBranch(ctx, dbData, oldBranch, DeleteOptions{Force: true}, remoteDbPro)
|
||||
}
|
||||
|
||||
func CopyBranch(ctx context.Context, dEnv *env.DoltEnv, oldBranch, newBranch string, force bool) error {
|
||||
@@ -113,27 +113,27 @@ type DeleteOptions struct {
|
||||
Remote bool
|
||||
}
|
||||
|
||||
func DeleteBranch(ctx context.Context, dbData env.DbData, config *env.DoltCliConfig, brName string, opts DeleteOptions) error {
|
||||
var dref ref.DoltRef
|
||||
func DeleteBranch(ctx context.Context, dbData env.DbData, brName string, opts DeleteOptions, remoteDbPro env.RemoteDbProvider) error {
|
||||
var branchRef ref.DoltRef
|
||||
if opts.Remote {
|
||||
var err error
|
||||
dref, err = ref.NewRemoteRefFromPathStr(brName)
|
||||
branchRef, err = ref.NewRemoteRefFromPathStr(brName)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
dref = ref.NewBranchRef(brName)
|
||||
if ref.Equals(dbData.Rsr.CWBHeadRef(), dref) {
|
||||
branchRef = ref.NewBranchRef(brName)
|
||||
if ref.Equals(dbData.Rsr.CWBHeadRef(), branchRef) {
|
||||
return ErrCOBranchDelete
|
||||
}
|
||||
}
|
||||
|
||||
return DeleteBranchOnDB(ctx, dbData, config, dref, opts)
|
||||
return DeleteBranchOnDB(ctx, dbData, branchRef, opts, remoteDbPro)
|
||||
}
|
||||
|
||||
func DeleteBranchOnDB(ctx context.Context, dbData env.DbData, config *env.DoltCliConfig, dref ref.DoltRef, opts DeleteOptions) error {
|
||||
ddb := dbData.Ddb
|
||||
hasRef, err := ddb.HasRef(ctx, dref)
|
||||
func DeleteBranchOnDB(ctx context.Context, dbdata env.DbData, branchRef ref.DoltRef, opts DeleteOptions, pro env.RemoteDbProvider) error {
|
||||
ddb := dbdata.Ddb
|
||||
hasRef, err := ddb.HasRef(ctx, branchRef)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -142,36 +142,27 @@ func DeleteBranchOnDB(ctx context.Context, dbData env.DbData, config *env.DoltCl
|
||||
}
|
||||
|
||||
if !opts.Force && !opts.Remote {
|
||||
ms, err := doltdb.NewCommitSpec(env.GetDefaultInitBranch(config))
|
||||
// check to see if the branch is fully merged into its parent
|
||||
trackedBranches, err := dbdata.Rsr.GetBranches()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
init, err := ddb.Resolve(ctx, ms, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cs, err := doltdb.NewCommitSpec(dref.String())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cm, err := ddb.Resolve(ctx, cs, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isMerged, _ := init.CanFastReverseTo(ctx, cm)
|
||||
if err != nil && !errors.Is(err, doltdb.ErrUpToDate) {
|
||||
return err
|
||||
}
|
||||
if !isMerged {
|
||||
return ErrUnmergedBranchDelete
|
||||
trackedBranch, hasUpstream := trackedBranches[branchRef.GetPath()]
|
||||
if hasUpstream {
|
||||
err = validateBranchMergedIntoUpstream(ctx, dbdata, branchRef, trackedBranch.Remote, pro)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
err = validateBranchMergedIntoCurrentWorkingBranch(ctx, dbdata, branchRef)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wsRef, err := ref.WorkingSetRefForHead(dref)
|
||||
wsRef, err := ref.WorkingSetRefForHead(branchRef)
|
||||
if err != nil {
|
||||
if !errors.Is(err, ref.ErrWorkingSetUnsupported) {
|
||||
return err
|
||||
@@ -183,7 +174,98 @@ func DeleteBranchOnDB(ctx context.Context, dbData env.DbData, config *env.DoltCl
|
||||
}
|
||||
}
|
||||
|
||||
return ddb.DeleteBranch(ctx, dref)
|
||||
return ddb.DeleteBranch(ctx, branchRef)
|
||||
}
|
||||
|
||||
// validateBranchMergedIntoCurrentWorkingBranch returns an error if the given branch is not fully merged into the HEAD of the current branch.
|
||||
func validateBranchMergedIntoCurrentWorkingBranch(ctx context.Context, dbdata env.DbData, branch ref.DoltRef) error {
|
||||
branchSpec, err := doltdb.NewCommitSpec(branch.GetPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
branchHead, err := dbdata.Ddb.Resolve(ctx, branchSpec, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cwbCs, err := doltdb.NewCommitSpec("HEAD")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cwbHead, err := dbdata.Ddb.Resolve(ctx, cwbCs, dbdata.Rsr.CWBHeadRef())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
isMerged, err := branchHead.CanFastForwardTo(ctx, cwbHead)
|
||||
if err != nil {
|
||||
if errors.Is(err, doltdb.ErrUpToDate) {
|
||||
return nil
|
||||
}
|
||||
if errors.Is(err, doltdb.ErrIsAhead) {
|
||||
return ErrUnmergedBranch
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
if !isMerged {
|
||||
return ErrUnmergedBranch
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// validateBranchMergedIntoUpstream returns an error if the branch provided is not fully merged into its upstream
|
||||
func validateBranchMergedIntoUpstream(ctx context.Context, dbdata env.DbData, branch ref.DoltRef, remoteName string, pro env.RemoteDbProvider) error {
|
||||
remotes, err := dbdata.Rsr.GetRemotes()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
remote, ok := remotes[remoteName]
|
||||
if !ok {
|
||||
// TODO: skip error?
|
||||
return fmt.Errorf("remote %s not found", remoteName)
|
||||
}
|
||||
|
||||
remoteDb, err := pro.GetRemoteDB(ctx, dbdata.Ddb.ValueReadWriter().Format(), remote, false)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
cs, err := doltdb.NewCommitSpec(branch.GetPath())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
remoteBranchHead, err := remoteDb.Resolve(ctx, cs, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
localBranchHead, err := dbdata.Ddb.Resolve(ctx, cs, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
canFF, err := localBranchHead.CanFastForwardTo(ctx, remoteBranchHead)
|
||||
if err != nil {
|
||||
if errors.Is(err, doltdb.ErrUpToDate) {
|
||||
return nil
|
||||
}
|
||||
if errors.Is(err, doltdb.ErrIsAhead) {
|
||||
return ErrUnmergedBranch
|
||||
}
|
||||
return err
|
||||
}
|
||||
|
||||
if !canFF {
|
||||
return ErrUnmergedBranch
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func CreateBranchWithStartPt(ctx context.Context, dbData env.DbData, newBranch, startPt string, force bool) error {
|
||||
|
||||
+8
@@ -98,6 +98,14 @@ type DoltEnv struct {
|
||||
IgnoreLockFile bool
|
||||
}
|
||||
|
||||
func (dEnv *DoltEnv) GetRemoteDB(ctx context.Context, format *types.NomsBinFormat, r Remote, withCaching bool) (*doltdb.DoltDB, error) {
|
||||
if withCaching {
|
||||
return r.GetRemoteDB(ctx, format, dEnv)
|
||||
} else {
|
||||
return r.GetRemoteDBWithoutCaching(ctx, format, dEnv)
|
||||
}
|
||||
}
|
||||
|
||||
// Load loads the DoltEnv for the .dolt directory determined by resolving the specified urlStr with the specified Filesys.
|
||||
func Load(ctx context.Context, hdp HomeDirProvider, fs filesys.Filesys, urlStr string, version string) *DoltEnv {
|
||||
cfg, cfgErr := LoadDoltCliConfig(hdp, fs)
|
||||
|
||||
+6
@@ -22,6 +22,7 @@ import (
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/ref"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/filesys"
|
||||
"github.com/dolthub/dolt/go/store/hash"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
type RepoStateReader interface {
|
||||
@@ -46,6 +47,11 @@ type RepoStateWriter interface {
|
||||
UpdateBranch(name string, new BranchConfig) error
|
||||
}
|
||||
|
||||
// RemoteDbProvider is an interface for getting a database from a remote
|
||||
type RemoteDbProvider interface {
|
||||
GetRemoteDB(ctx context.Context, format *types.NomsBinFormat, r Remote, withCaching bool) (*doltdb.DoltDB, error)
|
||||
}
|
||||
|
||||
type DbData struct {
|
||||
Ddb *doltdb.DoltDB
|
||||
Rsw RepoStateWriter
|
||||
|
||||
@@ -303,11 +303,11 @@ func (p DoltDatabaseProvider) AllDatabases(ctx *sql.Context) (all []sql.Database
|
||||
return all
|
||||
}
|
||||
|
||||
func (p DoltDatabaseProvider) GetRemoteDB(ctx *sql.Context, srcDB *doltdb.DoltDB, r env.Remote, withCaching bool) (*doltdb.DoltDB, error) {
|
||||
func (p DoltDatabaseProvider) GetRemoteDB(ctx context.Context, format *types.NomsBinFormat, r env.Remote, withCaching bool) (*doltdb.DoltDB, error) {
|
||||
if withCaching {
|
||||
return r.GetRemoteDB(ctx, srcDB.ValueReadWriter().Format(), p.remoteDialer)
|
||||
return r.GetRemoteDB(ctx, format, p.remoteDialer)
|
||||
}
|
||||
return r.GetRemoteDBWithoutCaching(ctx, srcDB.ValueReadWriter().Format(), p.remoteDialer)
|
||||
return r.GetRemoteDBWithoutCaching(ctx, format, p.remoteDialer)
|
||||
}
|
||||
|
||||
func (p DoltDatabaseProvider) CreateDatabase(ctx *sql.Context, name string) error {
|
||||
|
||||
@@ -146,7 +146,7 @@ func doDoltBackup(ctx *sql.Context, args []string) (int, error) {
|
||||
return statusErr, fmt.Errorf("unrecognized dolt_backup parameter: %s", apr.Arg(0))
|
||||
}
|
||||
|
||||
destDb, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb, b, true)
|
||||
destDb, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb.ValueReadWriter().Format(), b, true)
|
||||
if err != nil {
|
||||
return statusErr, fmt.Errorf("error loading backup destination: %w", err)
|
||||
}
|
||||
|
||||
@@ -111,7 +111,7 @@ func renameBranch(ctx *sql.Context, dbData env.DbData, apr *argparser.ArgParseRe
|
||||
return err
|
||||
}
|
||||
|
||||
err := actions.RenameBranch(ctx, dbData, loadConfig(ctx), oldBranchName, newBranchName, force)
|
||||
err := actions.RenameBranch(ctx, dbData, oldBranchName, newBranchName, sess.Provider(), force)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -162,6 +162,7 @@ func deleteBranches(ctx *sql.Context, dbData env.DbData, apr *argparser.ArgParse
|
||||
}
|
||||
|
||||
var updateFS = false
|
||||
dSess := dsess.DSessFromSess(ctx.Session)
|
||||
for _, branchName := range apr.Args {
|
||||
if len(branchName) == 0 {
|
||||
return EmptyBranchNameErr
|
||||
@@ -174,9 +175,9 @@ func deleteBranches(ctx *sql.Context, dbData env.DbData, apr *argparser.ArgParse
|
||||
return err
|
||||
}
|
||||
}
|
||||
err = actions.DeleteBranch(ctx, dbData, loadConfig(ctx), branchName, actions.DeleteOptions{
|
||||
err = actions.DeleteBranch(ctx, dbData, branchName, actions.DeleteOptions{
|
||||
Force: force,
|
||||
})
|
||||
}, dSess.Provider())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ func doDoltFetch(ctx *sql.Context, args []string) (int, error) {
|
||||
|
||||
updateMode := ref.UpdateMode{Force: apr.Contains(cli.ForceFlag)}
|
||||
|
||||
srcDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb, remote, false)
|
||||
srcDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb.ValueReadWriter().Format(), remote, false)
|
||||
if err != nil {
|
||||
return 1, err
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ func doDoltPull(ctx *sql.Context, args []string) (int, int, error) {
|
||||
return noConflictsOrViolations, threeWayMerge, err
|
||||
}
|
||||
|
||||
srcDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb, pullSpec.Remote, false)
|
||||
srcDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb.ValueReadWriter().Format(), pullSpec.Remote, false)
|
||||
if err != nil {
|
||||
return noConflictsOrViolations, threeWayMerge, fmt.Errorf("failed to get remote db; %w", err)
|
||||
}
|
||||
|
||||
@@ -70,7 +70,7 @@ func doDoltPush(ctx *sql.Context, args []string) (int, error) {
|
||||
if err != nil {
|
||||
return cmdFailure, err
|
||||
}
|
||||
remoteDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb, opts.Remote, true)
|
||||
remoteDB, err := sess.Provider().GetRemoteDB(ctx, dbData.Ddb.ValueReadWriter().Format(), opts.Remote, true)
|
||||
if err != nil {
|
||||
return 1, actions.HandleInitRemoteStorageClientErr(opts.Remote.Name, opts.Remote.Url, err)
|
||||
}
|
||||
|
||||
@@ -15,12 +15,15 @@
|
||||
package dsess
|
||||
|
||||
import (
|
||||
"context"
|
||||
|
||||
"github.com/dolthub/go-mysql-server/sql"
|
||||
"gopkg.in/src-d/go-errors.v1"
|
||||
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/doltdb"
|
||||
"github.com/dolthub/dolt/go/libraries/doltcore/env"
|
||||
"github.com/dolthub/dolt/go/libraries/utils/filesys"
|
||||
"github.com/dolthub/dolt/go/store/types"
|
||||
)
|
||||
|
||||
// ErrRevisionDbNotFound is thrown when a RevisionDatabaseProvider cannot find a specified revision database.
|
||||
@@ -66,6 +69,7 @@ type RemoteReadReplicaDatabase interface {
|
||||
type DoltDatabaseProvider interface {
|
||||
sql.MutableDatabaseProvider
|
||||
RevisionDatabaseProvider
|
||||
// env.RemoteDbProvider
|
||||
|
||||
// FileSystem returns the filesystem used by this provider, rooted at the data directory for all databases.
|
||||
FileSystem() filesys.Filesys
|
||||
@@ -77,7 +81,7 @@ type DoltDatabaseProvider interface {
|
||||
// withCaching defines whether the remoteDB gets cached or not.
|
||||
// This function replaces env.Remote's GetRemoteDB method during SQL session to access dialer in order
|
||||
// to get remote database associated to the env.Remote object.
|
||||
GetRemoteDB(ctx *sql.Context, srcDB *doltdb.DoltDB, r env.Remote, withCaching bool) (*doltdb.DoltDB, error)
|
||||
GetRemoteDB(ctx context.Context, format *types.NomsBinFormat, r env.Remote, withCaching bool) (*doltdb.DoltDB, error)
|
||||
// CloneDatabaseFromRemote clones the database from the specified remoteURL as a new database in this provider.
|
||||
// dbName is the name for the new database, branch is an optional parameter indicating which branch to clone
|
||||
// (otherwise all branches are cloned), remoteName is the name for the remote created in the new database, and
|
||||
@@ -113,7 +117,7 @@ func (e emptyRevisionDatabaseProvider) IsRevisionDatabase(_ *sql.Context, _ stri
|
||||
return false, nil
|
||||
}
|
||||
|
||||
func (e emptyRevisionDatabaseProvider) GetRemoteDB(ctx *sql.Context, srcDB *doltdb.DoltDB, r env.Remote, withCaching bool) (*doltdb.DoltDB, error) {
|
||||
func (e emptyRevisionDatabaseProvider) GetRemoteDB(ctx context.Context, format *types.NomsBinFormat, r env.Remote, withCaching bool) (*doltdb.DoltDB, error) {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
|
||||
@@ -1713,7 +1713,7 @@ var DoltBranchScripts = []queries.ScriptTest{
|
||||
{
|
||||
// Trying to delete a branch with unpushed changes fails without force option
|
||||
Query: "CALL DOLT_BRANCH('-d', 'myNewBranchWithCommit')",
|
||||
ExpectedErrStr: "attempted to delete a branch that is not fully merged into its parent; use `-f` to force",
|
||||
ExpectedErrStr: "branch is not fully merged",
|
||||
},
|
||||
{
|
||||
Query: "CALL DOLT_BRANCH('-df', 'myNewBranchWithCommit')",
|
||||
|
||||
@@ -47,3 +47,95 @@ teardown() {
|
||||
run dolt sql -q 'show tables'
|
||||
[[ "$output" =~ "test" ]] || false
|
||||
}
|
||||
|
||||
@test "branch: deleting an unmerged branch with a remote" {
|
||||
mkdir -p remotes/origin
|
||||
dolt remote add origin file://./remotes/origin
|
||||
dolt sql -q "create table t1 (id int primary key);"
|
||||
dolt commit -Am "initial commit"
|
||||
dolt branch b1
|
||||
dolt branch b2
|
||||
dolt branch b3
|
||||
|
||||
dolt push --set-upstream origin b1
|
||||
dolt push --set-upstream origin b2
|
||||
dolt push --set-upstream origin b3
|
||||
|
||||
# b1 is one commit ahead of the remote
|
||||
dolt checkout b1
|
||||
dolt sql -q "create table t2 (id int primary key);"
|
||||
dolt commit -Am "new table"
|
||||
|
||||
# b2 is even with the remote
|
||||
|
||||
# b3 is one commit behind the remote
|
||||
dolt checkout b3
|
||||
dolt sql -q "create table t2 (id int primary key);"
|
||||
dolt commit -Am "new table"
|
||||
dolt push origin b3
|
||||
dolt reset --hard HEAD~
|
||||
|
||||
dolt checkout main
|
||||
run dolt branch -d b1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "branch 'b1' is not fully merged" ]] || false
|
||||
[[ "$output" =~ "run 'dolt branch -D b1'" ]] || false
|
||||
|
||||
dolt branch -D b1
|
||||
dolt branch -d b2
|
||||
dolt branch -d b3
|
||||
|
||||
run dolt branch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ! "$output" =~ "b1" ]] || false
|
||||
[[ ! "$output" =~ "b2" ]] || false
|
||||
[[ ! "$output" =~ "b3" ]] || false
|
||||
}
|
||||
|
||||
@test "branch: deleting an unmerged branch with no remote" {
|
||||
dolt sql -q "create table t1 (id int primary key);"
|
||||
dolt commit -Am "commit 1"
|
||||
dolt sql -q "create table t2 (id int primary key);"
|
||||
dolt commit -Am "commit 2"
|
||||
dolt branch b1
|
||||
dolt branch b2
|
||||
dolt branch b3
|
||||
|
||||
# b1 is one commit ahead of main
|
||||
dolt checkout b1
|
||||
dolt sql -q "create table t3 (id int primary key);"
|
||||
dolt commit -Am "new table"
|
||||
# two additional copies
|
||||
dolt branch b1-1
|
||||
dolt branch b1-2
|
||||
|
||||
# b2 is even with main
|
||||
|
||||
# b3 is one commit behind main
|
||||
dolt checkout b3
|
||||
dolt reset --hard HEAD~
|
||||
|
||||
dolt checkout main
|
||||
run dolt branch -d b1
|
||||
[ "$status" -ne 0 ]
|
||||
[[ "$output" =~ "branch 'b1' is not fully merged" ]] || false
|
||||
[[ "$output" =~ "run 'dolt branch -D b1'" ]] || false
|
||||
|
||||
dolt branch -D b1
|
||||
|
||||
dolt checkout b1-1
|
||||
# this works because it's even with the checked out branch (but not with main)
|
||||
dolt branch -d b1-2
|
||||
|
||||
dolt checkout main
|
||||
dolt branch -D b1-1
|
||||
dolt branch -d b2
|
||||
dolt branch -d b3
|
||||
|
||||
run dolt branch
|
||||
[ "$status" -eq 0 ]
|
||||
[[ ! "$output" =~ "b1" ]] || false
|
||||
[[ ! "$output" =~ "b2" ]] || false
|
||||
[[ ! "$output" =~ "b3" ]] || false
|
||||
}
|
||||
|
||||
|
||||
@@ -18,23 +18,6 @@ teardown() {
|
||||
teardown_common
|
||||
}
|
||||
|
||||
@test "sql-branch: DOLT_BRANCH works" {
|
||||
run dolt branch
|
||||
[[ ! "$output" =~ "new_branch" ]] || false
|
||||
|
||||
run dolt sql -q "call dolt_branch('new-branch')"
|
||||
[ $status -eq 0 ]
|
||||
|
||||
# should create new branch and should not checkout the new branch
|
||||
run dolt status
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" =~ "main" ]] || false
|
||||
|
||||
run dolt branch
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" =~ "new-branch" ]] || false
|
||||
}
|
||||
|
||||
@test "sql-branch: CALL DOLT_BRANCH works" {
|
||||
run dolt branch
|
||||
[[ ! "$output" =~ "new_branch" ]] || false
|
||||
@@ -69,20 +52,7 @@ teardown() {
|
||||
[[ "$output" =~ "new-branch" ]] || false
|
||||
}
|
||||
|
||||
@test "sql-branch: DOLT_BRANCH throws error" {
|
||||
# branches that already exist
|
||||
dolt branch existing_branch
|
||||
run dolt sql -q "call dolt_branch('existing_branch')"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "fatal: A branch named 'existing_branch' already exists." ]] || false
|
||||
|
||||
# empty branch
|
||||
run dolt sql -q "call dolt_branch('')"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "error: cannot branch empty string" ]] || false
|
||||
}
|
||||
|
||||
@test "sql-branch: CALL DOLT_BRANCH throws error" {
|
||||
@test "sql-branch: CALL DOLT_BRANCH error cases" {
|
||||
# branches that already exist
|
||||
dolt branch existing_branch
|
||||
run dolt sql -q "CALL DOLT_BRANCH('existing_branch')"
|
||||
@@ -95,37 +65,6 @@ teardown() {
|
||||
[[ "$output" =~ "error: cannot branch empty string" ]]
|
||||
}
|
||||
|
||||
@test "sql-branch: DOLT_BRANCH -c copies not current branch and stays on current branch" {
|
||||
dolt add . && dolt commit -m "0, 1, and 2 in test table"
|
||||
run dolt status
|
||||
[[ "$output" =~ "main" ]] || false
|
||||
|
||||
dolt checkout -b original
|
||||
dolt sql -q "insert into test values (4);"
|
||||
dolt add .
|
||||
dolt commit -m "add 4 in original"
|
||||
|
||||
dolt checkout main
|
||||
|
||||
# Current branch should be still main with test table without entry 4
|
||||
run dolt sql << SQL
|
||||
call dolt_branch('-c', 'original', 'copy');
|
||||
SELECT * FROM test WHERE pk > 3;
|
||||
SQL
|
||||
[ $status -eq 0 ]
|
||||
[[ ! "$output" =~ "4" ]] || false
|
||||
|
||||
run dolt status
|
||||
[ $status -eq 0 ]
|
||||
[[ "$output" =~ "main" ]] || false
|
||||
|
||||
run dolt checkout copy
|
||||
[ $status -eq 0 ]
|
||||
|
||||
run dolt sql -q "SELECT * FROM test WHERE pk > 3;"
|
||||
[[ "$output" =~ "4" ]] || false
|
||||
}
|
||||
|
||||
@test "sql-branch: CALL DOLT_BRANCH -c copies not current branch and stays on current branch" {
|
||||
dolt add . && dolt commit -m "0, 1, and 2 in test table"
|
||||
run dolt status
|
||||
@@ -157,37 +96,6 @@ SQL
|
||||
[[ "$output" =~ "4" ]] || false
|
||||
}
|
||||
|
||||
@test "sql-branch: DOLT_BRANCH -c throws error on error cases" {
|
||||
run dolt status
|
||||
[[ "$output" =~ "main" ]] || false
|
||||
|
||||
# branch copying from is empty
|
||||
run dolt sql -q "call dolt_branch('-c','','copy')"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "error: cannot branch empty string" ]] || false
|
||||
|
||||
# branch copying to is empty
|
||||
run dolt sql -q "call dolt_branch('-c','main','')"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "error: cannot branch empty string" ]] || false
|
||||
|
||||
dolt branch 'existing_branch'
|
||||
run dolt branch
|
||||
[[ "$output" =~ "main" ]] || false
|
||||
[[ "$output" =~ "existing_branch" ]] || false
|
||||
[[ ! "$output" =~ "original" ]] || false
|
||||
|
||||
# branch copying from that don't exist
|
||||
run dolt sql -q "call dolt_branch('-c', 'original', 'copy');"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "fatal: A branch named 'original' not found" ]] || false
|
||||
|
||||
# branch copying to that exists
|
||||
run dolt sql -q "call dolt_branch('-c', 'main', 'existing_branch');"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "fatal: A branch named 'existing_branch' already exists." ]] || false
|
||||
}
|
||||
|
||||
@test "sql-branch: CALL DOLT_BRANCH -c throws error on error cases" {
|
||||
run dolt status
|
||||
[[ "$output" =~ "main" ]] || false
|
||||
@@ -219,19 +127,6 @@ SQL
|
||||
[[ "$output" =~ "fatal: A branch named 'existing_branch' already exists." ]]
|
||||
}
|
||||
|
||||
@test "sql-branch: DOLT_BRANCH works as insert into dolt_branches table" {
|
||||
dolt add . && dolt commit -m "1, 2, and 3 in test table"
|
||||
|
||||
run dolt sql -q "SELECT hash FROM dolt_branches WHERE name='main';"
|
||||
[ $status -eq 0 ]
|
||||
mainhash=$output
|
||||
|
||||
dolt sql -q "call dolt_branch('feature-branch');"
|
||||
run dolt sql -q "SELECT hash FROM dolt_branches WHERE name='feature-branch';"
|
||||
[ $status -eq 0 ]
|
||||
[ "$output" = "$mainhash" ]
|
||||
}
|
||||
|
||||
@test "sql-branch: CALL DOLT_BRANCH works as insert into dolt_branches table" {
|
||||
dolt add . && dolt commit -m "1, 2, and 3 in test table"
|
||||
|
||||
@@ -245,29 +140,6 @@ SQL
|
||||
[ "$output" = "$mainhash" ]
|
||||
}
|
||||
|
||||
@test "sql-branch: call dolt_branch to rename and delete" {
|
||||
dolt add . && dolt commit -m "1, 2, and 3 in test table"
|
||||
dolt branch new_branch
|
||||
|
||||
run dolt sql -q "call dolt_branch('-m', 'new_branch', 'changed');"
|
||||
[ $status -eq 0 ]
|
||||
|
||||
run dolt sql -q "call dolt_branch('-d', 'changed');"
|
||||
[ $status -eq 0 ]
|
||||
|
||||
dolt branch branch_with_unpushed_commit
|
||||
dolt checkout branch_with_unpushed_commit
|
||||
dolt commit --allow-empty -am 'empty commit'
|
||||
dolt checkout main
|
||||
|
||||
run dolt sql -q "call dolt_branch('-d', 'branch_with_unpushed_commit');"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "attempted to delete a branch that is not fully merged" ]] || false
|
||||
|
||||
run dolt sql -q "call dolt_branch('-D', 'branch_with_unpushed_commit');"
|
||||
[ $status -eq 0 ]
|
||||
}
|
||||
|
||||
@test "sql-branch: CALL DOLT_BRANCH to rename and delete" {
|
||||
dolt add . && dolt commit -m "1, 2, and 3 in test table"
|
||||
dolt branch new_branch
|
||||
@@ -285,7 +157,7 @@ SQL
|
||||
|
||||
run dolt sql -q "CALL DOLT_BRANCH('-d', 'branch_with_unpushed_commit');"
|
||||
[ $status -eq 1 ]
|
||||
[[ "$output" =~ "attempted to delete a branch that is not fully merged" ]] || false
|
||||
[[ "$output" =~ "not fully merged" ]] || false
|
||||
|
||||
run dolt sql -q "CALL DOLT_BRANCH('-D', 'branch_with_unpushed_commit');"
|
||||
[ $status -eq 0 ]
|
||||
|
||||
Reference in New Issue
Block a user