Merge pull request #9879 from dolthub/taylor/fix-resolve

Fix dolt conflicts resolve for resolving one table at a time
This commit is contained in:
Taylor Bantle
2025-09-24 13:55:34 -07:00
committed by GitHub
3 changed files with 110 additions and 3 deletions

View File

@@ -146,6 +146,11 @@ func printConflicts(queryist cli.Queryist, sqlCtx *sql.Context, tblNames []strin
}
}
// if there are no unmerged tables, return early
if len(mergeStatus.unmergedTables) == 0 {
return nil
}
// next print data conflicts
for _, tblName := range mergeStatus.unmergedTables {
shouldShowTable := isStringInArray(tblName, tblNames)
@@ -294,6 +299,11 @@ func getMergeStatus(queryist cli.Queryist, sqlCtx *sql.Context) (mergeStatus, er
return ms, errors.New("error: multiple rows in dolt_merge_status")
}
// No active merge; return default merge status (isMerging=false)
if len(rows) == 0 {
return ms, nil
}
row := rows[0]
ms.isMerging, err = commands.GetTinyIntColAsBool(row[0])
if err != nil {
@@ -304,7 +314,11 @@ func getMergeStatus(queryist cli.Queryist, sqlCtx *sql.Context) (mergeStatus, er
ms.sourceCommit = row[2].(string)
ms.target = row[3].(string)
unmergedTables := row[4].(string)
ms.unmergedTables = strings.Split(unmergedTables, ", ")
if unmergedTables == "" {
ms.unmergedTables = []string{}
} else {
ms.unmergedTables = strings.Split(unmergedTables, ", ")
}
}
return ms, nil

View File

@@ -31,9 +31,9 @@ import (
var resDocumentation = cli.CommandDocumentationContent{
ShortDesc: "Automatically resolves all conflicts taking either ours or theirs for the given tables",
LongDesc: `
When a merge finds conflicting changes, it documents them in the dolt_conflicts table. A conflict is between two versions: ours (the rows at the destination branch head) and theirs (the rows at the source branch head).
When a merge finds conflicting changes, it documents them in the dolt_conflicts table. A conflict is between two versions: ours (the rows at the destination branch head) and theirs (the rows at the source branch head).
dolt conflicts resolve will automatically resolve the conflicts by taking either the ours or theirs versions for each row.
dolt conflicts resolve will automatically resolve the conflicts by taking either the ours or theirs versions for each row.
`,
Synopsis: []string{
`--ours|--theirs {{.LessThan}}table{{.GreaterThan}}...`,
@@ -100,6 +100,13 @@ func (cmd ResolveCmd) Exec(ctx context.Context, commandStr string, args []string
return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
// Allow committing transactions that still have unresolved conflicts. This mirrors behavior in other
// commands (e.g. rebase) and prevents autocommit from rolling back when resolving one table at a time
// while other tables remain conflicted.
if _, err = cli.GetRowsForSql(queryist.Queryist, queryist.Context, "set @@dolt_allow_commit_conflicts=1;"); err != nil {
return commands.HandleVErrAndExitCode(errhand.VerboseErrorFromError(err), usage)
}
var verr errhand.VerboseError
if apr.ContainsAny(autoResolverParams...) {
verr = autoResolve(queryist.Queryist, queryist.Context, apr)

View File

@@ -17,6 +17,21 @@ basic_conflict() {
dolt commit -am "main commit"
}
two_conflicts() {
dolt sql -q "create table t (i int primary key, t text)"
dolt sql -q "create table t2 (i int primary key, t text)"
dolt add .
dolt commit -am "init commit"
dolt checkout -b other
dolt sql -q "insert into t values (1,'other')"
dolt sql -q "insert into t2 values (1,'other2')"
dolt commit -am "other commit"
dolt checkout main
dolt sql -q "insert into t values (1,'main')"
dolt sql -q "insert into t2 values (1,'main2')"
dolt commit -am "main commit"
}
teardown() {
assert_feature_version
teardown_common
@@ -156,6 +171,77 @@ teardown() {
[[ $output =~ "other" ]] || false
}
@test "conflicts-resolve: two conflicted tables, resolve theirs all" {
two_conflicts
run dolt sql -q "select * from t"
[ $status -eq 0 ]
[[ $output =~ "main" ]] || false
run dolt sql -q "select * from t2"
[ $status -eq 0 ]
[[ $output =~ "main2" ]] || false
run dolt merge other
[ $status -eq 1 ]
[[ $output =~ "Automatic merge failed" ]] || false
run dolt conflicts cat .
[ $status -eq 0 ]
[[ "$output" =~ "i" ]] || false
run dolt conflicts resolve --theirs .
[ $status -eq 0 ]
run dolt conflicts cat .
[ $status -eq 0 ]
! [[ "$output" =~ "i" ]] || false
run dolt sql -q "select * from t"
[ $status -eq 0 ]
[[ $output =~ "other" ]] || false
run dolt sql -q "select * from t2"
[ $status -eq 0 ]
[[ $output =~ "other2" ]] || false
}
@test "conflicts-resolve: two conflicted tables, resolve theirs one table, ours other table" {
two_conflicts
run dolt sql -q "select * from t"
[ $status -eq 0 ]
[[ $output =~ "main" ]] || false
run dolt sql -q "select * from t2"
[ $status -eq 0 ]
[[ $output =~ "main2" ]] || false
run dolt merge other
[ $status -eq 1 ]
[[ $output =~ "Automatic merge failed" ]] || false
run dolt conflicts cat .
[ $status -eq 0 ]
[[ "$output" =~ "i" ]] || false
run dolt conflicts resolve --theirs t
[ $status -eq 0 ]
run dolt sql -q "select * from t"
[ $status -eq 0 ]
[[ $output =~ "other" ]] || false
run dolt conflicts resolve --ours t2
[ $status -eq 0 ]
run dolt sql -q "select * from t2"
[ $status -eq 0 ]
[[ $output =~ "main2" ]] || false
run dolt conflicts cat .
[ $status -eq 0 ]
[ "$output" = "" ]
! [[ "$output" =~ "i" ]] || false
}
@test "conflicts-resolve: merge main into other, resolve with ours" {
basic_conflict