mirror of
https://github.com/dolthub/dolt.git
synced 2026-02-11 18:49:14 -06:00
@@ -101,7 +101,22 @@ func (cmd ResetCmd) Exec(ctx context.Context, commandStr string, args []string,
|
||||
|
||||
err = actions.ResetHard(ctx, dEnv, arg, workingRoot, stagedRoot, headRoot)
|
||||
} else {
|
||||
stagedRoot, err = actions.ResetSoft(ctx, dEnv.DbData(), apr, stagedRoot, headRoot)
|
||||
// Check whether the input argument is a ref.
|
||||
if apr.NArg() == 1 {
|
||||
argToCheck := apr.Arg(0)
|
||||
|
||||
ok := actions.ValidateIsRef(ctx, argToCheck, dEnv.DoltDB, dEnv.RepoStateReader())
|
||||
|
||||
// This is a valid ref
|
||||
if ok {
|
||||
err = actions.ResetSoftToRef(ctx, dEnv.DbData(), apr.Arg(0))
|
||||
return handleResetError(err, usage)
|
||||
}
|
||||
}
|
||||
|
||||
tables := apr.Args()
|
||||
|
||||
stagedRoot, err = actions.ResetSoft(ctx, dEnv.DbData(), tables, stagedRoot, headRoot)
|
||||
|
||||
if err != nil {
|
||||
return handleResetError(err, usage)
|
||||
@@ -171,7 +186,12 @@ func printNotStaged(ctx context.Context, dEnv *env.DoltEnv, staged *doltdb.RootV
|
||||
func handleResetError(err error, usage cli.UsagePrinter) int {
|
||||
if actions.IsTblNotExist(err) {
|
||||
tbls := actions.GetTablesForError(err)
|
||||
bdr := errhand.BuildDError("Invalid Table(s):")
|
||||
|
||||
// In case the ref does not exist.
|
||||
bdr := errhand.BuildDError("Invalid Ref or Table:")
|
||||
if len(tbls) > 1 {
|
||||
bdr = errhand.BuildDError("Invalid Table(s):")
|
||||
}
|
||||
|
||||
for _, tbl := range tbls {
|
||||
bdr.AddDetails("\t" + tbl)
|
||||
|
||||
@@ -87,7 +87,7 @@ type CommitSpec struct {
|
||||
// * remotes/origin/master~~
|
||||
// * refs/heads/my-feature-branch^2~
|
||||
//
|
||||
// Constructing a |CommitSpec| does not mean the sepcified branch or commit
|
||||
// Constructing a |CommitSpec| does not mean the specified branch or commit
|
||||
// exists. This carries a description of how to find the specified commit. See
|
||||
// |doltdb.Resolve| for resolving a |CommitSpec| to a |Commit|.
|
||||
func NewCommitSpec(cSpecStr string) (*CommitSpec, error) {
|
||||
|
||||
51
go/libraries/doltcore/env/actions/reset.go
vendored
51
go/libraries/doltcore/env/actions/reset.go
vendored
@@ -175,8 +175,8 @@ func ResetSoftTables(ctx context.Context, dbData env.DbData, apr *argparser.ArgP
|
||||
return stagedRoot, nil
|
||||
}
|
||||
|
||||
func ResetSoft(ctx context.Context, dbData env.DbData, apr *argparser.ArgParseResults, stagedRoot, headRoot *doltdb.RootValue) (*doltdb.RootValue, error) {
|
||||
tables, err := getUnionedTables(ctx, apr.Args(), stagedRoot, headRoot)
|
||||
func ResetSoft(ctx context.Context, dbData env.DbData, tables []string, stagedRoot, headRoot *doltdb.RootValue) (*doltdb.RootValue, error) {
|
||||
tables, err := getUnionedTables(ctx, tables, stagedRoot, headRoot)
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
@@ -211,6 +211,38 @@ func ResetSoft(ctx context.Context, dbData env.DbData, apr *argparser.ArgParseRe
|
||||
return stagedRoot, nil
|
||||
}
|
||||
|
||||
// ResetSoftToRef matches the `git reset --soft <REF>` pattern. It resets both staged and head to the previous ref
|
||||
// and leaves the working unset. The user can then choose to create a commit that contains all changes since the ref.
|
||||
func ResetSoftToRef(ctx context.Context, dbData env.DbData, cSpecStr string) error {
|
||||
cs, err := doltdb.NewCommitSpec(cSpecStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
newHead, err := dbData.Ddb.Resolve(ctx, cs, dbData.Rsr.CWBHeadRef())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
foundRoot, err := newHead.GetRootValue()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Changed the stage to old the root. Leave the working as is.
|
||||
_, err = env.UpdateStagedRoot(ctx, dbData.Ddb, dbData.Rsw, foundRoot)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// Update the head to this commit
|
||||
if err = dbData.Ddb.SetHeadToCommit(ctx, dbData.Rsr.CWBHeadRef(), newHead); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
||||
func getUnionedTables(ctx context.Context, tables []string, stagedRoot, headRoot *doltdb.RootValue) ([]string, error) {
|
||||
if len(tables) == 0 || (len(tables) == 1 && tables[0] == ".") {
|
||||
var err error
|
||||
@@ -258,3 +290,18 @@ func resetStaged(ctx context.Context, ddb *doltdb.DoltDB, rsw env.RepoStateWrite
|
||||
|
||||
return updatedRoot, env.UpdateStagedRootWithVErr(ddb, rsw, updatedRoot)
|
||||
}
|
||||
|
||||
// ValidateIsRef validates whether the input parameter is a valid cString
|
||||
func ValidateIsRef(ctx context.Context, cSpecStr string, ddb *doltdb.DoltDB, rsr env.RepoStateReader) bool {
|
||||
cs, err := doltdb.NewCommitSpec(cSpecStr)
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
_, err = ddb.Resolve(ctx, cs, rsr.CWBHeadRef())
|
||||
if err != nil {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -205,6 +205,8 @@ func TestJSONStructuralSharing(t *testing.T) {
|
||||
|
||||
err = db.Flush(ctx)
|
||||
require.NoError(t, err)
|
||||
err = db.(datas.GarbageCollector).GC(ctx)
|
||||
require.NoError(t, err)
|
||||
after := ts.Len()
|
||||
|
||||
// flush creates a single chunk
|
||||
|
||||
@@ -328,7 +328,7 @@ SQL
|
||||
dolt add .
|
||||
run dolt reset LICENSE.md invalid
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "Invalid Table(s)" ]] || false
|
||||
[[ "$output" =~ "Invalid Ref or Table" ]] || false
|
||||
[[ "$output" =~ "invalid" ]] || false
|
||||
run dolt status
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
@@ -204,4 +204,201 @@ SQL
|
||||
@test "status: dolt reset --hard with more than one additional arg throws an error " {
|
||||
run dolt reset --hard HEAD HEAD2
|
||||
[ "$status" -eq 1 ]
|
||||
}
|
||||
|
||||
@test "status: dolt reset hard with ~ works" {
|
||||
dolt sql -q "CREATE TABLE test (pk int PRIMARY KEY);"
|
||||
dolt commit -am "cm1"
|
||||
|
||||
dolt sql -q "INSERT INTO test values (1);"
|
||||
dolt commit -am "cm2"
|
||||
|
||||
dolt sql -q "INSERT INTO test VALUES (2);"
|
||||
dolt commit -am "cm3"
|
||||
|
||||
# Do a hard reset back one commit and confirm the appropriate values.
|
||||
run dolt reset --hard HEAD~1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run dolt sql -q "SELECT sum(pk) FROM test;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
|
||||
# Since this is a hard reset double check the status
|
||||
run dolt status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "On branch master" ]] || false
|
||||
[[ "$output" =~ "nothing to commit, working tree clean" ]] || false
|
||||
|
||||
# Run again with ~2 this time
|
||||
dolt sql -q "INSERT INTO test VALUES (2);"
|
||||
dolt commit -am "cm3"
|
||||
|
||||
# Do a hard reset back two commits and confirm the appropriate values.
|
||||
run dolt reset --hard HEAD~2
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
run dolt sql -q "SELECT sum(pk) FROM test;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "NULL" ]] || false
|
||||
|
||||
# Since this is a hard reset double check the status
|
||||
run dolt status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "On branch master" ]] || false
|
||||
[[ "$output" =~ "nothing to commit, working tree clean" ]] || false
|
||||
}
|
||||
|
||||
@test "status: dolt reset soft with ~ works" {
|
||||
dolt sql -q "CREATE TABLE test (pk int PRIMARY KEY);"
|
||||
dolt commit -am "cm1"
|
||||
|
||||
dolt sql -q "INSERT INTO test values (1);"
|
||||
dolt commit -am "cm2"
|
||||
|
||||
# Make a dirty change
|
||||
dolt sql -q "INSERT INTO test values (2)"
|
||||
run dolt reset HEAD~
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Verify that the changes are still there
|
||||
run dolt sql -q "SELECT sum(pk) FROM test;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
|
||||
# Now verify that commit log has changes
|
||||
run dolt sql -q "SELECT count(*) from dolt_log"
|
||||
[[ "$output" =~ "2" ]] || false
|
||||
|
||||
run dolt reset HEAD~1
|
||||
[ "$status" -eq 0 ]
|
||||
|
||||
# Verify that the changes are still there
|
||||
run dolt sql -q "SELECT sum(pk) FROM test;"
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "3" ]] || false
|
||||
|
||||
run dolt status
|
||||
[[ "$output" =~ "Untracked files:" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt add <table|doc>\" to include in what will be committed)" ]] || false
|
||||
[[ "$output" =~ " new table: test" ]] || false
|
||||
|
||||
# Now verify that commit log has changes
|
||||
run dolt sql -q "SELECT count(*) from dolt_log"
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
}
|
||||
|
||||
@test "status: dolt reset works with commit hash ref" {
|
||||
dolt sql -q "CREATE TABLE tb1 (pk int PRIMARY KEY);"
|
||||
dolt sql -q "INSERT INTO tb1 values (1);"
|
||||
dolt commit -am "cm1"
|
||||
|
||||
cm1=$(get_head_commit)
|
||||
|
||||
dolt sql -q "CREATE TABLE tb2 (pk int PRIMARY KEY);"
|
||||
dolt sql -q "INSERT INTO tb2 values (11);"
|
||||
dolt commit -am "cm2"
|
||||
|
||||
cm2=$(get_head_commit)
|
||||
|
||||
dolt sql -q "CREATE TABLE tb3 (pk int PRIMARY KEY);"
|
||||
dolt sql -q "INSERT INTO tb3 values (11);"
|
||||
dolt commit -am "cm3"
|
||||
|
||||
cm3=$(get_head_commit)
|
||||
|
||||
# Try a soft reset to commit 3. Nothing should change
|
||||
dolt reset $cm3
|
||||
run dolt status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "On branch master" ]] || false
|
||||
[[ "$output" =~ "nothing to commit, working tree clean" ]] || false
|
||||
|
||||
# Do a soft reset to commit 2.
|
||||
dolt reset $cm2
|
||||
run dolt status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "Untracked files:" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt add <table|doc>\" to include in what will be committed)" ]] || false
|
||||
[[ "$output" =~ " new table: tb3" ]] || false
|
||||
! [[ "$output" =~ " new table: tb2" ]] || false
|
||||
|
||||
run dolt sql -q "SELECT COUNT(*) FROM tb3"
|
||||
[[ "$output" =~ "1" ]] || false
|
||||
|
||||
run dolt sql -q "SELECT COUNT(*) FROM dolt_log"
|
||||
[[ "$output" =~ "3" ]] || false # includes init commit
|
||||
|
||||
dolt commit -am "commit 3"
|
||||
|
||||
# Do a soft reset to commit 1
|
||||
dolt reset $cm1
|
||||
run dolt status
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "Untracked files:" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt add <table|doc>\" to include in what will be committed)" ]] || false
|
||||
[[ "$output" =~ " new table: tb3" ]] || false
|
||||
[[ "$output" =~ " new table: tb2" ]] || false
|
||||
! [[ "$output" =~ " new table: tb1" ]] || false
|
||||
|
||||
run dolt sql -q "SELECT COUNT(*) FROM dolt_log"
|
||||
[[ "$output" =~ "2" ]] || false # includes init commit
|
||||
}
|
||||
|
||||
@test "status: dolt reset works with branch ref" {
|
||||
dolt sql -q "CREATE TABLE tbl(pk int);"
|
||||
dolt sql -q "INSERT into tbl VALUES (1)"
|
||||
dolt commit -am "cm1"
|
||||
|
||||
# create a new branch and make a change
|
||||
dolt checkout -b test
|
||||
dolt sql -q "INSERT INTO tbl VALUES (2),(3)"
|
||||
dolt sql -q "CREATE TABLE tbl2(pk int);"
|
||||
dolt commit -am "test cm1"
|
||||
|
||||
# go back to master and merge
|
||||
dolt checkout master
|
||||
dolt merge test
|
||||
dolt sql -q "INSERT INTO tbl VALUES (4)"
|
||||
dolt commit -am "cm2"
|
||||
|
||||
# execute the reset
|
||||
dolt reset test
|
||||
run dolt status
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "Changes not staged for commit:" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt add <table>\" to update what will be committed)" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt checkout <table>\" to discard changes in working directory)" ]] || false
|
||||
[[ "$output" =~ " modified: tbl" ]] || false
|
||||
! [[ "$output" =~ " new table: tb2" ]] || false
|
||||
}
|
||||
|
||||
@test "status: dolt reset ref properly manages staged changes as well" {
|
||||
dolt sql -q "CREATE TABLE tbl(pk int);"
|
||||
dolt sql -q "INSERT into tbl VALUES (1)"
|
||||
dolt commit -am "cm1"
|
||||
|
||||
dolt sql -q "INSERT INTO tbl VALUES (2)"
|
||||
dolt add .
|
||||
|
||||
dolt reset HEAD
|
||||
run dolt status
|
||||
|
||||
[ "$status" -eq 0 ]
|
||||
[[ "$output" =~ "Changes not staged for commit:" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt add <table>\" to update what will be committed)" ]] || false
|
||||
[[ "$output" =~ " (use \"dolt checkout <table>\" to discard changes in working directory)" ]] || false
|
||||
[[ "$output" =~ " modified: tbl" ]] || false
|
||||
}
|
||||
|
||||
@test "status: dolt reset throws errors for unknown ref/table" {
|
||||
run dolt reset test
|
||||
[ "$status" -eq 1 ]
|
||||
[[ "$output" =~ "Invalid Ref or Table" ]] || false
|
||||
[[ "$output" =~ "test" ]] || false
|
||||
}
|
||||
|
||||
get_head_commit() {
|
||||
dolt log -n 1 | grep -m 1 commit | cut -c 8-
|
||||
}
|
||||
Reference in New Issue
Block a user