Skip to content

Commit 32dd148

Browse files
authored
Merge pull request #590 from dolthub/taylor/resolve-tables
web,graphql: Table-specific conflicts resolve
2 parents 5379822 + 574cd55 commit 32dd148

File tree

18 files changed

+315
-142
lines changed

18 files changed

+315
-142
lines changed

graphql-server/schema.gql

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ type Mutation {
416416
doltClone(databaseName: String!, ownerName: String!, remoteDbName: String!): Boolean!
417417
loadDataFile(schemaName: String, tableName: String!, refName: String!, databaseName: String!, importOp: ImportOperation!, fileType: FileType!, file: Upload!, modifier: LoadDataModifier): Boolean!
418418
mergePull(fromBranchName: String!, toBranchName: String!, databaseName: String!, author: AuthorInfo): Boolean!
419-
mergeAndResolveConflicts(author: AuthorInfo, fromBranchName: String!, toBranchName: String!, databaseName: String!, conflictResolveType: ConflictResolveType!): Boolean!
419+
mergeAndResolveConflicts(author: AuthorInfo, fromBranchName: String!, toBranchName: String!, databaseName: String!, resolveOursTables: [String!]!, resolveTheirsTables: [String!]!): Boolean!
420420
addRemote(remoteName: String!, databaseName: String!, remoteUrl: String!): String!
421421
deleteRemote(databaseName: String!, remoteName: String!): Boolean!
422422
pullFromRemote(remoteName: String!, databaseName: String!, refName: String!, branchName: String!): PullRes!
@@ -449,9 +449,4 @@ enum LoadDataModifier {
449449
input AuthorInfo {
450450
name: String!
451451
email: String!
452-
}
453-
454-
enum ConflictResolveType {
455-
Ours
456-
Theirs
457452
}

graphql-server/src/pulls/pull.enums.ts

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,3 @@ export enum PullState {
77
}
88

99
registerEnumType(PullState, { name: "PullState" });
10-
11-
export enum ConflictResolveType {
12-
Ours = "ours",
13-
Theirs = "theirs",
14-
}
15-
16-
registerEnumType(ConflictResolveType, { name: "ConflictResolveType" });

graphql-server/src/pulls/pull.resolver.ts

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
import { CommitResolver } from "../commits/commit.resolver";
1010
import { ConnectionProvider } from "../connections/connection.provider";
1111
import { AuthorInfo, PullArgs } from "../utils/commonTypes";
12-
import { ConflictResolveType } from "./pull.enums";
1312
import { PullWithDetails, fromAPIModelPullWithDetails } from "./pull.model";
1413

1514
@ArgsType()
@@ -20,8 +19,11 @@ class MergePullArgs extends PullArgs {
2019

2120
@ArgsType()
2221
class MergeAndResolveArgs extends MergePullArgs {
23-
@Field(_type => ConflictResolveType)
24-
conflictResolveType: ConflictResolveType;
22+
@Field(_type => [String])
23+
resolveOursTables: string[];
24+
25+
@Field(_type => [String])
26+
resolveTheirsTables: string[];
2527
}
2628

2729
@Resolver(_of => PullWithDetails)
@@ -66,7 +68,8 @@ export class PullResolver {
6668
fromBranchName: args.fromBranchName,
6769
toBranchName: args.toBranchName,
6870
author: args.author,
69-
conflictResolveType: args.conflictResolveType,
71+
theirsTables: args.resolveTheirsTables,
72+
oursTables: args.resolveOursTables,
7073
});
7174
return true;
7275
}

graphql-server/src/queryFactory/dolt/index.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,8 @@ export class DoltQueryFactory
329329
async callMergeWithResolveConflicts(
330330
args: t.BranchesArgs & {
331331
author?: t.CommitAuthor;
332-
conflictResolveType: string;
332+
oursTables: string[];
333+
theirsTables: string[];
333334
},
334335
): Promise<boolean> {
335336
return this.queryMultiple(
@@ -348,7 +349,18 @@ export class DoltQueryFactory
348349
]);
349350

350351
if (res.length && res[0].conflicts !== "0") {
351-
await query(qh.resolveConflicts, [`--${args.conflictResolveType}`]);
352+
if (args.oursTables.length) {
353+
await query(qh.getResolveConflicts(args.oursTables.length), [
354+
"--ours",
355+
...args.oursTables,
356+
]);
357+
}
358+
if (args.theirsTables.length) {
359+
await query(qh.getResolveConflicts(args.theirsTables.length), [
360+
"--theirs",
361+
...args.theirsTables,
362+
]);
363+
}
352364
await query(qh.getCommitMerge(!!args.author), params);
353365
} else {
354366
await query("ROLLBACK");

graphql-server/src/queryFactory/dolt/queries.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,11 @@ export const mergeConflictsSummaryQuery = `SELECT * FROM DOLT_PREVIEW_MERGE_CONF
8787

8888
export const mergeConflictsQuery = `SELECT * FROM DOLT_PREVIEW_MERGE_CONFLICTS(?, ?, ?) LIMIT ? OFFSET ?`;
8989

90-
export const resolveConflicts = `CALL DOLT_CONFLICTS_RESOLVE(?, '.')`;
90+
export const getResolveConflicts = (numTables: number) =>
91+
`CALL DOLT_CONFLICTS_RESOLVE(?, ${Array.from(
92+
{ length: numTables },
93+
() => `?`,
94+
).join(", ")})`;
9195

9296
export const getCommitMerge = (hasAuthor = false) =>
9397
`CALL DOLT_COMMIT("-Am", ?${getAuthorNameString(hasAuthor)})`;

graphql-server/src/queryFactory/doltgres/index.ts

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -336,16 +336,18 @@ export class DoltgresQueryFactory
336336
);
337337
}
338338

339+
// TODO: The dolt_conflicts_resolve function does not work in doltgres yet
339340
async callMergeWithResolveConflicts(
340341
args: t.BranchesArgs & {
341342
author?: t.CommitAuthor;
342-
conflictResolveType: string;
343+
oursTables: string[];
344+
theirsTables: string[];
343345
},
344346
): Promise<boolean> {
345347
return this.queryMultiple(
346348
async query => {
347-
await query("BEGIN");
348349
// await query("SET autocommit off");
350+
await query("BEGIN");
349351

350352
const msg = `Merge branch ${args.fromBranchName}`;
351353
const params = [msg];
@@ -358,7 +360,18 @@ export class DoltgresQueryFactory
358360
]);
359361

360362
if (res.length && res[0].conflicts !== "0") {
361-
await query(qh.resolveConflicts, [`--${args.conflictResolveType}`]);
363+
if (args.oursTables.length) {
364+
await query(qh.getResolveConflicts(args.oursTables.length), [
365+
"--ours",
366+
...args.oursTables.map(tableWithoutSchema),
367+
]);
368+
}
369+
if (args.theirsTables.length) {
370+
await query(qh.getResolveConflicts(args.theirsTables.length), [
371+
"--theirs",
372+
...args.theirsTables.map(tableWithoutSchema),
373+
]);
374+
}
362375
await query(qh.getCommitMerge(!!args.author), params);
363376
} else {
364377
await query("ROLLBACK");

graphql-server/src/queryFactory/doltgres/queries.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -95,10 +95,14 @@ export const mergeConflictsSummaryQuery = `SELECT * FROM DOLT_PREVIEW_MERGE_CONF
9595
export const getMergeConflictsQuery = (offset: number) =>
9696
`SELECT * FROM DOLT_PREVIEW_MERGE_CONFLICTS($1::text, $2::text, $3::text) LIMIT ${ROW_LIMIT + 1} OFFSET ${offset}`;
9797

98-
export const resolveConflicts = `SELECT DOLT_CONFLICTS_RESOLVE($1::text, '.')`;
98+
export const getResolveConflicts = (numTables: number) =>
99+
`SELECT DOLT_CONFLICTS_RESOLVE($1::text, ${Array.from(
100+
{ length: numTables },
101+
(_, i) => `$${i + 2}::text`,
102+
).join(", ")})`;
99103

100104
export const getCommitMerge = (hasAuthor = false) =>
101-
`CALL DOLT_COMMIT("-Am", $1::text${getAuthorNameString(hasAuthor, "$2::text")})`;
105+
`SELECT DOLT_COMMIT('-Am', $1::text${getAuthorNameString(hasAuthor, "$2::text")})`;
102106

103107
// TAGS
104108

graphql-server/src/queryFactory/index.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ export declare class QueryFactory {
142142
callMergeWithResolveConflicts(
143143
args: t.BranchesArgs & {
144144
author?: t.CommitAuthor;
145-
conflictResolveType: string;
145+
oursTables: string[];
146+
theirsTables: string[];
146147
},
147148
): Promise<boolean>;
148149

web/renderer/components/pageComponents/DatabasePage/ForPullConflicts/index.tsx

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import PullConflictBreadcrumbs from "@components/breadcrumbs/PullConflictBreadcrumbs";
2+
import DocsLink from "@components/links/DocsLink";
23
import NotDoltWrapper from "@components/util/NotDoltWrapper";
34
import { Loader } from "@dolthub/react-components";
5+
import { errorMatches } from "@lib/errors/helpers";
46
import { PullDiffParams } from "@lib/params";
57
import { pulls } from "@lib/urls";
68
import ForDefaultBranch from "../ForDefaultBranch";
@@ -46,19 +48,33 @@ type InnerProps = {
4648
function Inner(props: InnerProps) {
4749
const { activeTableName } = useConflictsContext();
4850
const res = useRowConflicts({ ...props.params, tableName: activeTableName });
51+
if (res.loading) return <Loader loaded={!res.loading} />;
52+
if (res.error && errorMatches("schema conflicts found", res.error)) {
53+
return (
54+
<div className={css.container}>
55+
<h3>Schema conflicts found for {activeTableName}</h3>
56+
<p>
57+
Cannot view data conflict rows until schema conflicts have been
58+
resolved. View instructions{" "}
59+
<DocsLink path="/sql-reference/version-control/merges#schema">
60+
here
61+
</DocsLink>
62+
.
63+
</p>
64+
</div>
65+
);
66+
}
4967
return (
5068
<div className={css.container}>
5169
<h3>
5270
Conflicted rows in <code>{activeTableName}</code>
5371
</h3>
54-
<Loader loaded={!res.loading}>
55-
<ConflictsTable
56-
state={res.state}
57-
fetchMore={res.fetchMore}
58-
hasMore={res.hasMore}
59-
error={res.error}
60-
/>
61-
</Loader>
72+
<ConflictsTable
73+
state={res.state}
74+
fetchMore={res.fetchMore}
75+
hasMore={res.hasMore}
76+
error={res.error}
77+
/>
6278
</div>
6379
);
6480
}

web/renderer/components/pageComponents/DatabasePage/ForPulls/PullActions/Merge/ErrorsWithDirections/MergeConflictsDirections.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@ export default function MergeConflictsDirections({ params }: Props) {
2626
<h3>Merge and Resolve Conflicts</h3>
2727
<div className={css.innerModal}>
2828
<p>
29-
Conflicts cannot be resolved on the web and must be resolved in a SQL
30-
shell.
29+
If you&apos;d like to manually resolve conflicts before merging,
30+
follow these steps using the SQL shell.
3131
</p>
3232
<p>
3333
<DocsLink path="/sql-reference/version-control/dolt-sql-procedures#dolt_merge">

0 commit comments

Comments
 (0)