@markjaquith/agency 2.74.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +29 -122
- package/cli-main.ts +10 -28
- package/cli.ts +1 -17
- package/package.json +1 -2
- package/schemas/agency-graph-v1.schema.json +1 -1
- package/src/cli-parser.test.ts +5 -19
- package/src/cli-parser.ts +12 -30
- package/src/cli.test.ts +6 -6
- package/src/commands/archive.test.ts +73 -1
- package/src/commands/archive.ts +18 -7
- package/src/commands/context.test.ts +0 -67
- package/src/commands/init.test.ts +1 -2
- package/src/commands/pr.test.ts +2 -87
- package/src/commands/pr.ts +2 -79
- package/src/commands/push.test.ts +1 -2
- package/src/graph-schema.ts +1 -1
- package/src/services/ArchiveBulkService.test.ts +1 -142
- package/src/services/ArchiveService.test.ts +1 -172
- package/src/services/ArchiveService.ts +59 -27
- package/src/services/ContextService.ts +3 -47
- package/src/services/DoctorService.ts +8 -24
- package/src/services/GraphService.test.ts +1 -0
- package/src/services/GraphService.ts +2 -5
- package/src/services/PhaseService.ts +70 -191
- package/src/services/PullRequestService.test.ts +1 -45
- package/src/services/PullRequestService.ts +1 -22
- package/src/services/PushService.test.ts +29 -295
- package/src/services/PushService.ts +10 -239
- package/src/services/RepositoryService.test.ts +1 -61
- package/src/services/RepositoryService.ts +2 -13
- package/src/services/ReviewService.test.ts +1 -84
- package/src/services/ReviewService.ts +9 -48
- package/src/services/SyncService.test.ts +0 -81
- package/src/services/SyncService.ts +12 -39
- package/src/services/TaskPhaseService.test.ts +0 -80
- package/src/services/TaskService.ts +1 -9
- package/src/services/VersionControlService.test.ts +4 -117
- package/src/services/VersionControlService.ts +3 -426
- package/src/services/WorkbaseService.test.ts +0 -20
- package/src/services/WorkbaseService.ts +1 -18
- package/src/services/WorktreeService.test.ts +1 -705
- package/src/services/WorktreeService.ts +395 -1604
- package/src/services/push-validation.ts +0 -7
- package/src/test-utils.ts +0 -4
- package/src/workbase/AGENTS.md +4 -5
- package/src/workbase/checkout-command.test.ts +1 -1
- package/src/workbase/checkout-command.ts +1 -1
- package/src/workbase/delivery-command.test.ts +4 -35
- package/src/workbase/delivery-command.ts +2 -15
- package/src/workbase/schemas.test.ts +0 -19
- package/src/workbase/schemas.ts +1 -2
- package/src/commands/vcs.test.ts +0 -75
- package/src/commands/vcs.ts +0 -72
- package/src/services/VcsMigrationService.test.ts +0 -348
- package/src/services/VcsMigrationService.ts +0 -857
- package/src/vcs-status-fast.ts +0 -310
- package/src/workbase/version-control.ts +0 -5
- package/src/workbase/workspace-command.test.ts +0 -70
- package/src/workbase/workspace-command.ts +0 -63
|
@@ -3,10 +3,10 @@ import { Effect } from "effect"
|
|
|
3
3
|
import { mkdir } from "node:fs/promises"
|
|
4
4
|
import { join } from "node:path"
|
|
5
5
|
import { cleanupTempDir, createTempDir, runTestEffect } from "../test-utils"
|
|
6
|
-
import { TaskService } from "./TaskService"
|
|
7
6
|
import { PushService } from "./PushService"
|
|
8
|
-
import {
|
|
7
|
+
import { TaskService } from "./TaskService"
|
|
9
8
|
import { WorktreeService } from "./WorktreeService"
|
|
9
|
+
import { parseGitCommits } from "./push-validation"
|
|
10
10
|
|
|
11
11
|
interface CommandResult {
|
|
12
12
|
readonly stdout: string
|
|
@@ -40,7 +40,7 @@ const requireCommand = async (args: readonly string[], cwd?: string) => {
|
|
|
40
40
|
}
|
|
41
41
|
|
|
42
42
|
describe("PushService", () => {
|
|
43
|
-
test("parses
|
|
43
|
+
test("parses batched Git commit metadata", () => {
|
|
44
44
|
const output = [
|
|
45
45
|
"abc123\0Agency Test\0agency@example.com\0First change\0\x1e",
|
|
46
46
|
"def456\0Agency Test\0agency@example.com\0Second change\0\x1e",
|
|
@@ -64,17 +64,14 @@ describe("PushService", () => {
|
|
|
64
64
|
await Promise.all(roots.splice(0).map(cleanupTempDir))
|
|
65
65
|
})
|
|
66
66
|
|
|
67
|
-
const setup = async (
|
|
67
|
+
const setup = async () => {
|
|
68
68
|
const root = await createTempDir()
|
|
69
69
|
roots.push(root)
|
|
70
70
|
const remote = join(root, "remote.git")
|
|
71
71
|
const seed = join(root, "seed")
|
|
72
72
|
const repository = join(root, "repos", "agency")
|
|
73
73
|
await mkdir(join(root, "repos"), { recursive: true })
|
|
74
|
-
await Bun.write(
|
|
75
|
-
join(root, "agency.json"),
|
|
76
|
-
`${JSON.stringify({ version: 2, vcs }, null, 2)}\n`,
|
|
77
|
-
)
|
|
74
|
+
await Bun.write(join(root, "agency.json"), '{"version":2,"vcs":"git"}\n')
|
|
78
75
|
await requireCommand([
|
|
79
76
|
"git",
|
|
80
77
|
"init",
|
|
@@ -93,27 +90,7 @@ describe("PushService", () => {
|
|
|
93
90
|
await requireCommand(["git", "commit", "-m", "Initial commit"], seed)
|
|
94
91
|
await requireCommand(["git", "remote", "add", "origin", remote], seed)
|
|
95
92
|
await requireCommand(["git", "push", "-u", "origin", "main"], seed)
|
|
96
|
-
|
|
97
|
-
await requireCommand([
|
|
98
|
-
"jj",
|
|
99
|
-
"git",
|
|
100
|
-
"clone",
|
|
101
|
-
"--no-colocate",
|
|
102
|
-
remote,
|
|
103
|
-
repository,
|
|
104
|
-
])
|
|
105
|
-
expect(await Bun.file(join(repository, ".git")).exists()).toBe(false)
|
|
106
|
-
await requireCommand(
|
|
107
|
-
["jj", "config", "set", "--repo", "user.name", "Agency Test"],
|
|
108
|
-
repository,
|
|
109
|
-
)
|
|
110
|
-
await requireCommand(
|
|
111
|
-
["jj", "config", "set", "--repo", "user.email", "agency@example.com"],
|
|
112
|
-
repository,
|
|
113
|
-
)
|
|
114
|
-
} else {
|
|
115
|
-
await requireCommand(["git", "clone", "--bare", remote, repository])
|
|
116
|
-
}
|
|
93
|
+
await requireCommand(["git", "clone", "--bare", remote, repository])
|
|
117
94
|
|
|
118
95
|
await runTestEffect(
|
|
119
96
|
TaskService.pipe(
|
|
@@ -158,27 +135,31 @@ describe("PushService", () => {
|
|
|
158
135
|
PushService.pipe(Effect.flatMap((service) => service.publish(taskPath))),
|
|
159
136
|
)
|
|
160
137
|
|
|
161
|
-
const remoteBranch = async (remote: string
|
|
138
|
+
const remoteBranch = async (remote: string) =>
|
|
162
139
|
(
|
|
163
140
|
await requireCommand([
|
|
164
141
|
"git",
|
|
165
142
|
"--git-dir",
|
|
166
143
|
remote,
|
|
167
144
|
"rev-parse",
|
|
168
|
-
|
|
145
|
+
"refs/heads/task/example",
|
|
169
146
|
])
|
|
170
147
|
).stdout
|
|
171
148
|
|
|
172
|
-
|
|
173
|
-
const fixture = await setup("git")
|
|
149
|
+
const configureAuthor = async (checkout: string) => {
|
|
174
150
|
await requireCommand(
|
|
175
151
|
["git", "config", "user.name", "Agency Test"],
|
|
176
|
-
|
|
152
|
+
checkout,
|
|
177
153
|
)
|
|
178
154
|
await requireCommand(
|
|
179
155
|
["git", "config", "user.email", "agency@example.com"],
|
|
180
|
-
|
|
156
|
+
checkout,
|
|
181
157
|
)
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
test("publishes a clean Git HEAD and establishes upstream tracking", async () => {
|
|
161
|
+
const fixture = await setup()
|
|
162
|
+
await configureAuthor(fixture.checkout)
|
|
182
163
|
await Bun.write(join(fixture.checkout, "feature.txt"), "published\n")
|
|
183
164
|
await requireCommand(["git", "add", "feature.txt"], fixture.checkout)
|
|
184
165
|
await requireCommand(
|
|
@@ -205,11 +186,11 @@ describe("PushService", () => {
|
|
|
205
186
|
})
|
|
206
187
|
|
|
207
188
|
test("rejects dirty, mismatched, and undescribed Git publication", async () => {
|
|
208
|
-
const dirty = await setup(
|
|
189
|
+
const dirty = await setup()
|
|
209
190
|
await Bun.write(join(dirty.checkout, "dirty.txt"), "dirty\n")
|
|
210
191
|
await expect(publish(dirty.taskPath)).rejects.toThrow("dirty Git worktree")
|
|
211
192
|
|
|
212
|
-
const mismatched = await setup(
|
|
193
|
+
const mismatched = await setup()
|
|
213
194
|
await requireCommand(
|
|
214
195
|
["git", "branch", "-m", "wrong-branch"],
|
|
215
196
|
mismatched.checkout,
|
|
@@ -218,15 +199,8 @@ describe("PushService", () => {
|
|
|
218
199
|
"does not match checked-out Git branch",
|
|
219
200
|
)
|
|
220
201
|
|
|
221
|
-
const undescribed = await setup(
|
|
222
|
-
await
|
|
223
|
-
["git", "config", "user.name", "Agency Test"],
|
|
224
|
-
undescribed.checkout,
|
|
225
|
-
)
|
|
226
|
-
await requireCommand(
|
|
227
|
-
["git", "config", "user.email", "agency@example.com"],
|
|
228
|
-
undescribed.checkout,
|
|
229
|
-
)
|
|
202
|
+
const undescribed = await setup()
|
|
203
|
+
await configureAuthor(undescribed.checkout)
|
|
230
204
|
await requireCommand(
|
|
231
205
|
["git", "commit", "--allow-empty", "--allow-empty-message", "-m", ""],
|
|
232
206
|
undescribed.checkout,
|
|
@@ -237,13 +211,8 @@ describe("PushService", () => {
|
|
|
237
211
|
})
|
|
238
212
|
|
|
239
213
|
test("rejects Git remote divergence after refreshing remote state", async () => {
|
|
240
|
-
const fixture = await setup(
|
|
241
|
-
|
|
242
|
-
["user.name", "Agency Test"],
|
|
243
|
-
["user.email", "agency@example.com"],
|
|
244
|
-
] as const) {
|
|
245
|
-
await requireCommand(["git", "config", key, value], fixture.checkout)
|
|
246
|
-
}
|
|
214
|
+
const fixture = await setup()
|
|
215
|
+
await configureAuthor(fixture.checkout)
|
|
247
216
|
await Bun.write(join(fixture.checkout, "feature.txt"), "first\n")
|
|
248
217
|
await requireCommand(["git", "add", "feature.txt"], fixture.checkout)
|
|
249
218
|
await requireCommand(
|
|
@@ -277,7 +246,7 @@ describe("PushService", () => {
|
|
|
277
246
|
})
|
|
278
247
|
|
|
279
248
|
test("requires working status and the declared Git base in history", async () => {
|
|
280
|
-
const open = await setup(
|
|
249
|
+
const open = await setup()
|
|
281
250
|
await runTestEffect(
|
|
282
251
|
TaskService.pipe(
|
|
283
252
|
Effect.flatMap((service) =>
|
|
@@ -289,15 +258,8 @@ describe("PushService", () => {
|
|
|
289
258
|
"status 'open'; status must be working",
|
|
290
259
|
)
|
|
291
260
|
|
|
292
|
-
const unrelated = await setup(
|
|
293
|
-
await
|
|
294
|
-
["git", "config", "user.name", "Agency Test"],
|
|
295
|
-
unrelated.checkout,
|
|
296
|
-
)
|
|
297
|
-
await requireCommand(
|
|
298
|
-
["git", "config", "user.email", "agency@example.com"],
|
|
299
|
-
unrelated.checkout,
|
|
300
|
-
)
|
|
261
|
+
const unrelated = await setup()
|
|
262
|
+
await configureAuthor(unrelated.checkout)
|
|
301
263
|
await requireCommand(
|
|
302
264
|
["git", "checkout", "--orphan", "unrelated"],
|
|
303
265
|
unrelated.checkout,
|
|
@@ -318,16 +280,9 @@ describe("PushService", () => {
|
|
|
318
280
|
)
|
|
319
281
|
})
|
|
320
282
|
|
|
321
|
-
test("rejects invalid Git
|
|
322
|
-
const
|
|
323
|
-
await
|
|
324
|
-
["git", "config", "user.name", "Agency Test"],
|
|
325
|
-
git.checkout,
|
|
326
|
-
)
|
|
327
|
-
await requireCommand(
|
|
328
|
-
["git", "config", "user.email", "agency@example.com"],
|
|
329
|
-
git.checkout,
|
|
330
|
-
)
|
|
283
|
+
test("rejects invalid Git authors", async () => {
|
|
284
|
+
const fixture = await setup()
|
|
285
|
+
await configureAuthor(fixture.checkout)
|
|
331
286
|
await requireCommand(
|
|
332
287
|
[
|
|
333
288
|
"git",
|
|
@@ -338,231 +293,10 @@ describe("PushService", () => {
|
|
|
338
293
|
"-m",
|
|
339
294
|
"Invalid author",
|
|
340
295
|
],
|
|
341
|
-
git.checkout,
|
|
342
|
-
)
|
|
343
|
-
await expect(publish(git.taskPath)).rejects.toThrow("has an invalid author")
|
|
344
|
-
|
|
345
|
-
if (!Bun.which("jj")) return
|
|
346
|
-
const jj = await setup("jj")
|
|
347
|
-
await requireCommand(
|
|
348
|
-
["jj", "describe", "-m", "Invalid author"],
|
|
349
|
-
jj.checkout,
|
|
350
|
-
)
|
|
351
|
-
await requireCommand(
|
|
352
|
-
["jj", "metaedit", "--author", "Bad <bad>"],
|
|
353
|
-
jj.checkout,
|
|
354
|
-
)
|
|
355
|
-
const changeId = (
|
|
356
|
-
await requireCommand(
|
|
357
|
-
["jj", "log", "--no-graph", "-r", "@", "-T", "change_id"],
|
|
358
|
-
jj.checkout,
|
|
359
|
-
)
|
|
360
|
-
).stdout
|
|
361
|
-
await expect(publish(jj.taskPath)).rejects.toThrow(
|
|
362
|
-
`Change ${changeId} has an invalid author. Run: jj metaedit -r ${changeId} --author 'Name <email>'`,
|
|
363
|
-
)
|
|
364
|
-
})
|
|
365
|
-
|
|
366
|
-
test("publishes a described jj working-copy change under the declared bookmark", async () => {
|
|
367
|
-
if (!Bun.which("jj")) return
|
|
368
|
-
const fixture = await setup("jj")
|
|
369
|
-
await Bun.write(join(fixture.checkout, "feature.txt"), "published\n")
|
|
370
|
-
await requireCommand(
|
|
371
|
-
["jj", "describe", "-m", "Add published feature"],
|
|
372
|
-
fixture.checkout,
|
|
373
|
-
)
|
|
374
|
-
|
|
375
|
-
const result = await publish(fixture.taskPath)
|
|
376
|
-
expect(result).toMatchObject({
|
|
377
|
-
vcs: "jj",
|
|
378
|
-
branch: "task/example",
|
|
379
|
-
base: "main",
|
|
380
|
-
remote: "origin",
|
|
381
|
-
})
|
|
382
|
-
expect(await remoteBranch(fixture.remote)).toBe(result.tip)
|
|
383
|
-
expect(
|
|
384
|
-
(
|
|
385
|
-
await requireCommand(
|
|
386
|
-
[
|
|
387
|
-
"jj",
|
|
388
|
-
"bookmark",
|
|
389
|
-
"list",
|
|
390
|
-
"--all-remotes",
|
|
391
|
-
"-T",
|
|
392
|
-
'if(name == "task/example" && remote == "origin", tracked, "")',
|
|
393
|
-
],
|
|
394
|
-
fixture.checkout,
|
|
395
|
-
)
|
|
396
|
-
).stdout,
|
|
397
|
-
).toBe("true")
|
|
398
|
-
|
|
399
|
-
await requireCommand(["jj", "new", "@"], fixture.checkout)
|
|
400
|
-
await Bun.write(join(fixture.checkout, "follow-up.txt"), "follow up\n")
|
|
401
|
-
await requireCommand(
|
|
402
|
-
["jj", "describe", "-m", "Add follow-up"],
|
|
403
|
-
fixture.checkout,
|
|
404
|
-
)
|
|
405
|
-
const advanced = await publish(fixture.taskPath)
|
|
406
|
-
expect(advanced.tip).not.toBe(result.tip)
|
|
407
|
-
expect(await remoteBranch(fixture.remote)).toBe(advanced.tip)
|
|
408
|
-
}, 15_000)
|
|
409
|
-
|
|
410
|
-
test("diagnoses a jj stack whose remote base advanced", async () => {
|
|
411
|
-
if (!Bun.which("jj")) return
|
|
412
|
-
const fixture = await setup("jj")
|
|
413
|
-
await Bun.write(join(fixture.checkout, "feature.txt"), "local\n")
|
|
414
|
-
await requireCommand(
|
|
415
|
-
["jj", "describe", "-m", "Local feature"],
|
|
416
|
-
fixture.checkout,
|
|
417
|
-
)
|
|
418
|
-
|
|
419
|
-
const other = join(fixture.root, "other-main")
|
|
420
|
-
await requireCommand(["git", "clone", fixture.remote, other])
|
|
421
|
-
await requireCommand(["git", "config", "user.name", "Other"], other)
|
|
422
|
-
await requireCommand(
|
|
423
|
-
["git", "config", "user.email", "other@example.com"],
|
|
424
|
-
other,
|
|
425
|
-
)
|
|
426
|
-
await Bun.write(join(other, "remote.txt"), "remote\n")
|
|
427
|
-
await requireCommand(["git", "add", "remote.txt"], other)
|
|
428
|
-
await requireCommand(["git", "commit", "-m", "Advance main"], other)
|
|
429
|
-
await requireCommand(["git", "push", "origin", "main"], other)
|
|
430
|
-
|
|
431
|
-
await expect(publish(fixture.taskPath)).rejects.toThrow(
|
|
432
|
-
"jj rebase -s 'roots(main@origin..@)' -d main@origin",
|
|
433
|
-
)
|
|
434
|
-
})
|
|
435
|
-
|
|
436
|
-
test("selects the described parent of a canonical jj post-commit working copy", async () => {
|
|
437
|
-
if (!Bun.which("jj")) return
|
|
438
|
-
const fixture = await setup("jj")
|
|
439
|
-
await Bun.write(join(fixture.checkout, "feature.txt"), "published\n")
|
|
440
|
-
await requireCommand(
|
|
441
|
-
["jj", "commit", "-m", "Add published feature"],
|
|
442
296
|
fixture.checkout,
|
|
443
297
|
)
|
|
444
|
-
const parent = (
|
|
445
|
-
await requireCommand(
|
|
446
|
-
["jj", "log", "--no-graph", "-r", "@-", "-T", "commit_id"],
|
|
447
|
-
fixture.checkout,
|
|
448
|
-
)
|
|
449
|
-
).stdout
|
|
450
|
-
|
|
451
|
-
const result = await publish(fixture.taskPath)
|
|
452
|
-
expect(result.tip).toBe(parent)
|
|
453
|
-
expect(await remoteBranch(fixture.remote)).toBe(parent)
|
|
454
|
-
})
|
|
455
|
-
|
|
456
|
-
test("preserves a described empty jj change and diagnoses missing semantics", async () => {
|
|
457
|
-
if (!Bun.which("jj")) return
|
|
458
|
-
const described = await setup("jj")
|
|
459
|
-
await requireCommand(
|
|
460
|
-
["jj", "describe", "-m", "Record intentional empty change"],
|
|
461
|
-
described.checkout,
|
|
462
|
-
)
|
|
463
|
-
const describedTip = (
|
|
464
|
-
await requireCommand(
|
|
465
|
-
["jj", "log", "--no-graph", "-r", "@", "-T", "commit_id"],
|
|
466
|
-
described.checkout,
|
|
467
|
-
)
|
|
468
|
-
).stdout
|
|
469
|
-
expect((await publish(described.taskPath)).tip).toBe(describedTip)
|
|
470
|
-
|
|
471
|
-
const undescribed = await setup("jj")
|
|
472
|
-
await Bun.write(join(undescribed.checkout, "feature.txt"), "missing\n")
|
|
473
|
-
const changeId = (
|
|
474
|
-
await requireCommand(
|
|
475
|
-
["jj", "log", "--no-graph", "-r", "@", "-T", "change_id"],
|
|
476
|
-
undescribed.checkout,
|
|
477
|
-
)
|
|
478
|
-
).stdout
|
|
479
|
-
await expect(publish(undescribed.taskPath)).rejects.toThrow(
|
|
480
|
-
`Change ${changeId} has no description. Run: jj describe -r ${changeId}`,
|
|
481
|
-
)
|
|
482
|
-
}, 15_000)
|
|
483
|
-
|
|
484
|
-
test("rejects an empty jj task and remote bookmark divergence", async () => {
|
|
485
|
-
if (!Bun.which("jj")) return
|
|
486
|
-
const empty = await setup("jj")
|
|
487
|
-
await expect(publish(empty.taskPath)).rejects.toThrow(
|
|
488
|
-
"No changes to publish after base 'main'",
|
|
489
|
-
)
|
|
490
|
-
|
|
491
|
-
const fixture = await setup("jj")
|
|
492
|
-
await Bun.write(join(fixture.checkout, "feature.txt"), "first\n")
|
|
493
|
-
await requireCommand(
|
|
494
|
-
["jj", "describe", "-m", "First change"],
|
|
495
|
-
fixture.checkout,
|
|
496
|
-
)
|
|
497
|
-
await publish(fixture.taskPath)
|
|
498
|
-
|
|
499
|
-
const other = join(fixture.root, "other")
|
|
500
|
-
await requireCommand(["git", "clone", fixture.remote, other])
|
|
501
|
-
await requireCommand(["git", "checkout", "task/example"], other)
|
|
502
|
-
await requireCommand(["git", "config", "user.name", "Other"], other)
|
|
503
|
-
await requireCommand(
|
|
504
|
-
["git", "config", "user.email", "other@example.com"],
|
|
505
|
-
other,
|
|
506
|
-
)
|
|
507
|
-
await Bun.write(join(other, "remote.txt"), "remote\n")
|
|
508
|
-
await requireCommand(["git", "add", "remote.txt"], other)
|
|
509
|
-
await requireCommand(["git", "commit", "-m", "Remote change"], other)
|
|
510
|
-
await requireCommand(["git", "push", "origin", "task/example"], other)
|
|
511
|
-
|
|
512
|
-
await requireCommand(["jj", "new", "@"], fixture.checkout)
|
|
513
|
-
await Bun.write(join(fixture.checkout, "local.txt"), "local\n")
|
|
514
|
-
await requireCommand(
|
|
515
|
-
["jj", "describe", "-m", "Local change"],
|
|
516
|
-
fixture.checkout,
|
|
517
|
-
)
|
|
518
|
-
await expect(publish(fixture.taskPath)).rejects.toThrow(
|
|
519
|
-
"refusing to move it",
|
|
520
|
-
)
|
|
521
|
-
}, 15_000)
|
|
522
|
-
|
|
523
|
-
test("rejects conflicted jj changes with an actionable change ID", async () => {
|
|
524
|
-
if (!Bun.which("jj")) return
|
|
525
|
-
const fixture = await setup("jj")
|
|
526
|
-
await Bun.write(join(fixture.checkout, "README.md"), "left\n")
|
|
527
|
-
await requireCommand(
|
|
528
|
-
["jj", "describe", "-m", "Left change"],
|
|
529
|
-
fixture.checkout,
|
|
530
|
-
)
|
|
531
|
-
await requireCommand(
|
|
532
|
-
["jj", "bookmark", "create", "left", "-r", "@"],
|
|
533
|
-
fixture.checkout,
|
|
534
|
-
)
|
|
535
|
-
await requireCommand(["jj", "new", "main@origin"], fixture.checkout)
|
|
536
|
-
await Bun.write(join(fixture.checkout, "README.md"), "right\n")
|
|
537
|
-
await requireCommand(
|
|
538
|
-
["jj", "describe", "-m", "Right change"],
|
|
539
|
-
fixture.checkout,
|
|
540
|
-
)
|
|
541
|
-
await requireCommand(
|
|
542
|
-
["jj", "bookmark", "create", "right", "-r", "@"],
|
|
543
|
-
fixture.checkout,
|
|
544
|
-
)
|
|
545
|
-
await requireCommand(["jj", "new", "left", "right"], fixture.checkout)
|
|
546
|
-
await requireCommand(
|
|
547
|
-
["jj", "describe", "-m", "Conflicted merge"],
|
|
548
|
-
fixture.checkout,
|
|
549
|
-
)
|
|
550
|
-
const changeId = (
|
|
551
|
-
await requireCommand(
|
|
552
|
-
["jj", "log", "--no-graph", "-r", "@", "-T", "change_id"],
|
|
553
|
-
fixture.checkout,
|
|
554
|
-
)
|
|
555
|
-
).stdout
|
|
556
|
-
expect(
|
|
557
|
-
(
|
|
558
|
-
await requireCommand(
|
|
559
|
-
["jj", "log", "--no-graph", "-r", "@", "-T", "conflict"],
|
|
560
|
-
fixture.checkout,
|
|
561
|
-
)
|
|
562
|
-
).stdout,
|
|
563
|
-
).toBe("true")
|
|
564
298
|
await expect(publish(fixture.taskPath)).rejects.toThrow(
|
|
565
|
-
|
|
299
|
+
"has an invalid author",
|
|
566
300
|
)
|
|
567
301
|
})
|
|
568
302
|
})
|