@fern-api/replay 0.7.0 → 0.8.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/dist/cli.cjs +170 -61
- package/dist/cli.cjs.map +1 -1
- package/dist/index.cjs +171 -60
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +19 -8
- package/dist/index.d.ts +19 -8
- package/dist/index.js +169 -61
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -133,6 +133,9 @@ var init_GitClient = __esm({
|
|
|
133
133
|
return false;
|
|
134
134
|
}
|
|
135
135
|
}
|
|
136
|
+
async getCommitBody(commitSha) {
|
|
137
|
+
return this.exec(["log", "-1", "--format=%B", commitSha]);
|
|
138
|
+
}
|
|
136
139
|
getRepoPath() {
|
|
137
140
|
return this.repoPath;
|
|
138
141
|
}
|
|
@@ -157,6 +160,9 @@ __export(index_exports, {
|
|
|
157
160
|
forget: () => forget,
|
|
158
161
|
isGenerationCommit: () => isGenerationCommit,
|
|
159
162
|
isReplayCommit: () => isReplayCommit,
|
|
163
|
+
isRevertCommit: () => isRevertCommit,
|
|
164
|
+
parseRevertedMessage: () => parseRevertedMessage,
|
|
165
|
+
parseRevertedSha: () => parseRevertedSha,
|
|
160
166
|
reset: () => reset,
|
|
161
167
|
resolve: () => resolve,
|
|
162
168
|
status: () => status,
|
|
@@ -182,6 +188,17 @@ function isGenerationCommit(commit) {
|
|
|
182
188
|
function isReplayCommit(commit) {
|
|
183
189
|
return commit.message.startsWith("[fern-replay]");
|
|
184
190
|
}
|
|
191
|
+
function isRevertCommit(message) {
|
|
192
|
+
return message.startsWith('Revert "');
|
|
193
|
+
}
|
|
194
|
+
function parseRevertedSha(fullBody) {
|
|
195
|
+
const match = fullBody.match(/This reverts commit ([0-9a-f]{40})\./);
|
|
196
|
+
return match?.[1];
|
|
197
|
+
}
|
|
198
|
+
function parseRevertedMessage(subject) {
|
|
199
|
+
const match = subject.match(/^Revert "(.+)"$/);
|
|
200
|
+
return match?.[1];
|
|
201
|
+
}
|
|
185
202
|
|
|
186
203
|
// src/LockfileManager.ts
|
|
187
204
|
var import_node_fs = require("fs");
|
|
@@ -344,14 +361,14 @@ var ReplayDetector = class {
|
|
|
344
361
|
const lock = this.lockManager.read();
|
|
345
362
|
const lastGen = this.getLastGeneration(lock);
|
|
346
363
|
if (!lastGen) {
|
|
347
|
-
return [];
|
|
364
|
+
return { patches: [], revertedPatchIds: [] };
|
|
348
365
|
}
|
|
349
366
|
const exists = await this.git.commitExists(lastGen.commit_sha);
|
|
350
367
|
if (!exists) {
|
|
351
368
|
this.warnings.push(
|
|
352
369
|
`Generation commit ${lastGen.commit_sha.slice(0, 7)} not found in git history. Skipping new patch detection. Existing lockfile patches will still be applied.`
|
|
353
370
|
);
|
|
354
|
-
return [];
|
|
371
|
+
return { patches: [], revertedPatchIds: [] };
|
|
355
372
|
}
|
|
356
373
|
const isAncestor = await this.git.isAncestor(lastGen.commit_sha, "HEAD");
|
|
357
374
|
if (!isAncestor) {
|
|
@@ -365,7 +382,7 @@ var ReplayDetector = class {
|
|
|
365
382
|
this.sdkOutputDir
|
|
366
383
|
]);
|
|
367
384
|
if (!log.trim()) {
|
|
368
|
-
return [];
|
|
385
|
+
return { patches: [], revertedPatchIds: [] };
|
|
369
386
|
}
|
|
370
387
|
const commits = this.parseGitLog(log);
|
|
371
388
|
const newPatches = [];
|
|
@@ -401,7 +418,60 @@ var ReplayDetector = class {
|
|
|
401
418
|
patch_content: patchContent
|
|
402
419
|
});
|
|
403
420
|
}
|
|
404
|
-
|
|
421
|
+
newPatches.reverse();
|
|
422
|
+
const revertedPatchIdSet = /* @__PURE__ */ new Set();
|
|
423
|
+
const revertIndicesToRemove = /* @__PURE__ */ new Set();
|
|
424
|
+
for (let i = 0; i < newPatches.length; i++) {
|
|
425
|
+
const patch = newPatches[i];
|
|
426
|
+
if (!isRevertCommit(patch.original_message)) continue;
|
|
427
|
+
let body = "";
|
|
428
|
+
try {
|
|
429
|
+
body = await this.git.getCommitBody(patch.original_commit);
|
|
430
|
+
} catch {
|
|
431
|
+
}
|
|
432
|
+
const revertedSha = parseRevertedSha(body);
|
|
433
|
+
const revertedMessage = parseRevertedMessage(patch.original_message);
|
|
434
|
+
let matchedExisting = false;
|
|
435
|
+
if (revertedSha) {
|
|
436
|
+
const existing = lock.patches.find((p) => p.original_commit === revertedSha);
|
|
437
|
+
if (existing) {
|
|
438
|
+
revertedPatchIdSet.add(existing.id);
|
|
439
|
+
revertIndicesToRemove.add(i);
|
|
440
|
+
matchedExisting = true;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
if (!matchedExisting && revertedMessage) {
|
|
444
|
+
const existing = lock.patches.find((p) => p.original_message === revertedMessage);
|
|
445
|
+
if (existing) {
|
|
446
|
+
revertedPatchIdSet.add(existing.id);
|
|
447
|
+
revertIndicesToRemove.add(i);
|
|
448
|
+
matchedExisting = true;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
if (matchedExisting) continue;
|
|
452
|
+
let matchedNew = false;
|
|
453
|
+
if (revertedSha) {
|
|
454
|
+
const idx = newPatches.findIndex(
|
|
455
|
+
(p, j) => j !== i && !revertIndicesToRemove.has(j) && p.original_commit === revertedSha
|
|
456
|
+
);
|
|
457
|
+
if (idx !== -1) {
|
|
458
|
+
revertIndicesToRemove.add(i);
|
|
459
|
+
revertIndicesToRemove.add(idx);
|
|
460
|
+
matchedNew = true;
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
if (!matchedNew && revertedMessage) {
|
|
464
|
+
const idx = newPatches.findIndex(
|
|
465
|
+
(p, j) => j !== i && !revertIndicesToRemove.has(j) && p.original_message === revertedMessage
|
|
466
|
+
);
|
|
467
|
+
if (idx !== -1) {
|
|
468
|
+
revertIndicesToRemove.add(i);
|
|
469
|
+
revertIndicesToRemove.add(idx);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
}
|
|
473
|
+
const filteredPatches = newPatches.filter((_, i) => !revertIndicesToRemove.has(i));
|
|
474
|
+
return { patches: filteredPatches, revertedPatchIds: [...revertedPatchIdSet] };
|
|
405
475
|
}
|
|
406
476
|
/**
|
|
407
477
|
* Compute content hash for deduplication.
|
|
@@ -412,31 +482,34 @@ var ReplayDetector = class {
|
|
|
412
482
|
const normalized = patchContent.split("\n").filter((line) => !line.startsWith("From ") && !line.startsWith("index ") && !line.startsWith("Date: ")).join("\n");
|
|
413
483
|
return `sha256:${(0, import_node_crypto.createHash)("sha256").update(normalized).digest("hex")}`;
|
|
414
484
|
}
|
|
415
|
-
/**
|
|
485
|
+
/**
|
|
486
|
+
* Detect patches via tree diff for non-linear history. Returns a composite patch.
|
|
487
|
+
* Revert reconciliation is skipped here because tree-diff produces a single composite
|
|
488
|
+
* patch from the aggregate diff — individual revert commits are not distinguishable.
|
|
489
|
+
*/
|
|
416
490
|
async detectPatchesViaTreeDiff(lastGen) {
|
|
417
491
|
const filesOutput = await this.git.exec(["diff", "--name-only", lastGen.commit_sha, "HEAD"]);
|
|
418
492
|
const files = filesOutput.trim().split("\n").filter(Boolean).filter((f) => !INFRASTRUCTURE_FILES.has(f)).filter((f) => !f.startsWith(".fern/"));
|
|
419
|
-
if (files.length === 0) return [];
|
|
493
|
+
if (files.length === 0) return { patches: [], revertedPatchIds: [] };
|
|
420
494
|
const diff = await this.git.exec(["diff", lastGen.commit_sha, "HEAD", "--", ...files]);
|
|
421
|
-
if (!diff.trim()) return [];
|
|
495
|
+
if (!diff.trim()) return { patches: [], revertedPatchIds: [] };
|
|
422
496
|
const contentHash = this.computeContentHash(diff);
|
|
423
497
|
const lock = this.lockManager.read();
|
|
424
498
|
if (lock.patches.some((p) => p.content_hash === contentHash)) {
|
|
425
|
-
return [];
|
|
499
|
+
return { patches: [], revertedPatchIds: [] };
|
|
426
500
|
}
|
|
427
501
|
const headSha = (await this.git.exec(["rev-parse", "HEAD"])).trim();
|
|
428
|
-
|
|
429
|
-
{
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
];
|
|
502
|
+
const compositePatch = {
|
|
503
|
+
id: `patch-composite-${headSha.slice(0, 8)}`,
|
|
504
|
+
content_hash: contentHash,
|
|
505
|
+
original_commit: headSha,
|
|
506
|
+
original_message: "Customer customizations (composite)",
|
|
507
|
+
original_author: "composite",
|
|
508
|
+
base_generation: lastGen.commit_sha,
|
|
509
|
+
files,
|
|
510
|
+
patch_content: diff
|
|
511
|
+
};
|
|
512
|
+
return { patches: [compositePatch], revertedPatchIds: [] };
|
|
440
513
|
}
|
|
441
514
|
parseGitLog(log) {
|
|
442
515
|
return log.trim().split("\n").map((line) => {
|
|
@@ -1038,6 +1111,36 @@ var import_node_fs2 = require("fs");
|
|
|
1038
1111
|
var import_node_path3 = require("path");
|
|
1039
1112
|
var import_minimatch2 = require("minimatch");
|
|
1040
1113
|
init_GitClient();
|
|
1114
|
+
|
|
1115
|
+
// src/conflict-utils.ts
|
|
1116
|
+
function stripConflictMarkers(content) {
|
|
1117
|
+
const lines = content.split("\n");
|
|
1118
|
+
const result = [];
|
|
1119
|
+
let inConflict = false;
|
|
1120
|
+
let inOurs = false;
|
|
1121
|
+
for (const line of lines) {
|
|
1122
|
+
if (line.startsWith("<<<<<<< ")) {
|
|
1123
|
+
inConflict = true;
|
|
1124
|
+
inOurs = true;
|
|
1125
|
+
continue;
|
|
1126
|
+
}
|
|
1127
|
+
if (inConflict && line === "=======") {
|
|
1128
|
+
inOurs = false;
|
|
1129
|
+
continue;
|
|
1130
|
+
}
|
|
1131
|
+
if (inConflict && line.startsWith(">>>>>>> ")) {
|
|
1132
|
+
inConflict = false;
|
|
1133
|
+
inOurs = false;
|
|
1134
|
+
continue;
|
|
1135
|
+
}
|
|
1136
|
+
if (!inConflict || inOurs) {
|
|
1137
|
+
result.push(line);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
return result.join("\n");
|
|
1141
|
+
}
|
|
1142
|
+
|
|
1143
|
+
// src/ReplayService.ts
|
|
1041
1144
|
var ReplayService = class {
|
|
1042
1145
|
git;
|
|
1043
1146
|
detector;
|
|
@@ -1105,7 +1208,7 @@ var ReplayService = class {
|
|
|
1105
1208
|
}
|
|
1106
1209
|
this.lockManager.save();
|
|
1107
1210
|
try {
|
|
1108
|
-
const redetectedPatches = await this.detector.detectNewPatches();
|
|
1211
|
+
const { patches: redetectedPatches } = await this.detector.detectNewPatches();
|
|
1109
1212
|
if (redetectedPatches.length > 0) {
|
|
1110
1213
|
const redetectedFiles = new Set(redetectedPatches.flatMap((p) => p.files));
|
|
1111
1214
|
const currentPatches = this.lockManager.getPatches();
|
|
@@ -1196,7 +1299,7 @@ var ReplayService = class {
|
|
|
1196
1299
|
};
|
|
1197
1300
|
}
|
|
1198
1301
|
async handleNoPatchesRegeneration(options) {
|
|
1199
|
-
const newPatches = await this.detector.detectNewPatches();
|
|
1302
|
+
const { patches: newPatches, revertedPatchIds } = await this.detector.detectNewPatches();
|
|
1200
1303
|
const warnings = [...this.detector.warnings];
|
|
1201
1304
|
if (options?.dryRun) {
|
|
1202
1305
|
return {
|
|
@@ -1205,11 +1308,18 @@ var ReplayService = class {
|
|
|
1205
1308
|
patchesApplied: 0,
|
|
1206
1309
|
patchesWithConflicts: 0,
|
|
1207
1310
|
patchesSkipped: 0,
|
|
1311
|
+
patchesReverted: revertedPatchIds.length,
|
|
1208
1312
|
conflicts: [],
|
|
1209
1313
|
wouldApply: newPatches,
|
|
1210
1314
|
warnings: warnings.length > 0 ? warnings : void 0
|
|
1211
1315
|
};
|
|
1212
1316
|
}
|
|
1317
|
+
for (const id of revertedPatchIds) {
|
|
1318
|
+
try {
|
|
1319
|
+
this.lockManager.removePatch(id);
|
|
1320
|
+
} catch {
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1213
1323
|
const commitOpts = options ? {
|
|
1214
1324
|
cliVersion: options.cliVersion ?? "unknown",
|
|
1215
1325
|
generatorVersions: options.generatorVersions ?? {},
|
|
@@ -1243,12 +1353,12 @@ var ReplayService = class {
|
|
|
1243
1353
|
await this.committer.stageAll();
|
|
1244
1354
|
}
|
|
1245
1355
|
}
|
|
1246
|
-
return this.buildReport("no-patches", newPatches, results, options, warnings, rebaseCounts);
|
|
1356
|
+
return this.buildReport("no-patches", newPatches, results, options, warnings, rebaseCounts, void 0, revertedPatchIds.length);
|
|
1247
1357
|
}
|
|
1248
1358
|
async handleNormalRegeneration(options) {
|
|
1249
1359
|
if (options?.dryRun) {
|
|
1250
1360
|
const existingPatches2 = this.lockManager.getPatches();
|
|
1251
|
-
const newPatches2 = await this.detector.detectNewPatches();
|
|
1361
|
+
const { patches: newPatches2, revertedPatchIds: dryRunReverted } = await this.detector.detectNewPatches();
|
|
1252
1362
|
const warnings2 = [...this.detector.warnings];
|
|
1253
1363
|
const allPatches2 = [...existingPatches2, ...newPatches2];
|
|
1254
1364
|
return {
|
|
@@ -1257,13 +1367,19 @@ var ReplayService = class {
|
|
|
1257
1367
|
patchesApplied: 0,
|
|
1258
1368
|
patchesWithConflicts: 0,
|
|
1259
1369
|
patchesSkipped: 0,
|
|
1370
|
+
patchesReverted: dryRunReverted.length,
|
|
1260
1371
|
conflicts: [],
|
|
1261
1372
|
wouldApply: allPatches2,
|
|
1262
1373
|
warnings: warnings2.length > 0 ? warnings2 : void 0
|
|
1263
1374
|
};
|
|
1264
1375
|
}
|
|
1265
1376
|
let existingPatches = this.lockManager.getPatches();
|
|
1377
|
+
const preRebasePatchIds = new Set(existingPatches.map((p) => p.id));
|
|
1266
1378
|
const preRebaseCounts = await this.preGenerationRebase(existingPatches);
|
|
1379
|
+
const postRebasePatchIds = new Set(this.lockManager.getPatches().map((p) => p.id));
|
|
1380
|
+
const removedByPreRebase = existingPatches.filter(
|
|
1381
|
+
(p) => preRebasePatchIds.has(p.id) && !postRebasePatchIds.has(p.id)
|
|
1382
|
+
);
|
|
1267
1383
|
existingPatches = this.lockManager.getPatches();
|
|
1268
1384
|
const seenHashes = /* @__PURE__ */ new Set();
|
|
1269
1385
|
for (const p of existingPatches) {
|
|
@@ -1274,8 +1390,28 @@ var ReplayService = class {
|
|
|
1274
1390
|
}
|
|
1275
1391
|
}
|
|
1276
1392
|
existingPatches = this.lockManager.getPatches();
|
|
1277
|
-
|
|
1393
|
+
let { patches: newPatches, revertedPatchIds } = await this.detector.detectNewPatches();
|
|
1278
1394
|
const warnings = [...this.detector.warnings];
|
|
1395
|
+
if (removedByPreRebase.length > 0) {
|
|
1396
|
+
const removedOriginalCommits = new Set(removedByPreRebase.map((p) => p.original_commit));
|
|
1397
|
+
const removedOriginalMessages = new Set(removedByPreRebase.map((p) => p.original_message));
|
|
1398
|
+
newPatches = newPatches.filter((p) => {
|
|
1399
|
+
if (removedOriginalCommits.has(p.original_commit)) return false;
|
|
1400
|
+
if (isRevertCommit(p.original_message)) {
|
|
1401
|
+
const revertedMsg = parseRevertedMessage(p.original_message);
|
|
1402
|
+
if (revertedMsg && removedOriginalMessages.has(revertedMsg)) return false;
|
|
1403
|
+
}
|
|
1404
|
+
return true;
|
|
1405
|
+
});
|
|
1406
|
+
}
|
|
1407
|
+
for (const id of revertedPatchIds) {
|
|
1408
|
+
try {
|
|
1409
|
+
this.lockManager.removePatch(id);
|
|
1410
|
+
} catch {
|
|
1411
|
+
}
|
|
1412
|
+
}
|
|
1413
|
+
const revertedSet = new Set(revertedPatchIds);
|
|
1414
|
+
existingPatches = existingPatches.filter((p) => !revertedSet.has(p.id));
|
|
1279
1415
|
const allPatches = [...existingPatches, ...newPatches];
|
|
1280
1416
|
const commitOpts = options ? {
|
|
1281
1417
|
cliVersion: options.cliVersion ?? "unknown",
|
|
@@ -1320,7 +1456,8 @@ var ReplayService = class {
|
|
|
1320
1456
|
options,
|
|
1321
1457
|
warnings,
|
|
1322
1458
|
rebaseCounts,
|
|
1323
|
-
preRebaseCounts
|
|
1459
|
+
preRebaseCounts,
|
|
1460
|
+
revertedPatchIds.length
|
|
1324
1461
|
);
|
|
1325
1462
|
}
|
|
1326
1463
|
/**
|
|
@@ -1513,36 +1650,6 @@ var ReplayService = class {
|
|
|
1513
1650
|
}
|
|
1514
1651
|
return { conflictResolved, conflictAbsorbed, contentRefreshed };
|
|
1515
1652
|
}
|
|
1516
|
-
/**
|
|
1517
|
-
* Strip conflict markers from file content, keeping the OURS (Generated) side.
|
|
1518
|
-
* Preserves clean patches' non-conflicting changes on shared files.
|
|
1519
|
-
*/
|
|
1520
|
-
stripConflictMarkers(content) {
|
|
1521
|
-
const lines = content.split("\n");
|
|
1522
|
-
const result = [];
|
|
1523
|
-
let inConflict = false;
|
|
1524
|
-
let inOurs = false;
|
|
1525
|
-
for (const line of lines) {
|
|
1526
|
-
if (line.startsWith("<<<<<<< ")) {
|
|
1527
|
-
inConflict = true;
|
|
1528
|
-
inOurs = true;
|
|
1529
|
-
continue;
|
|
1530
|
-
}
|
|
1531
|
-
if (inConflict && line === "=======") {
|
|
1532
|
-
inOurs = false;
|
|
1533
|
-
continue;
|
|
1534
|
-
}
|
|
1535
|
-
if (inConflict && line.startsWith(">>>>>>> ")) {
|
|
1536
|
-
inConflict = false;
|
|
1537
|
-
inOurs = false;
|
|
1538
|
-
continue;
|
|
1539
|
-
}
|
|
1540
|
-
if (!inConflict || inOurs) {
|
|
1541
|
-
result.push(line);
|
|
1542
|
-
}
|
|
1543
|
-
}
|
|
1544
|
-
return result.join("\n");
|
|
1545
|
-
}
|
|
1546
1653
|
/**
|
|
1547
1654
|
* After applyPatches(), strip conflict markers from conflicting files
|
|
1548
1655
|
* so only clean content is committed. Keeps the Generated (OURS) side.
|
|
@@ -1555,7 +1662,7 @@ var ReplayService = class {
|
|
|
1555
1662
|
const filePath = (0, import_node_path3.join)(this.outputDir, fileResult.file);
|
|
1556
1663
|
try {
|
|
1557
1664
|
const content = (0, import_node_fs2.readFileSync)(filePath, "utf-8");
|
|
1558
|
-
const stripped =
|
|
1665
|
+
const stripped = stripConflictMarkers(content);
|
|
1559
1666
|
(0, import_node_fs2.writeFileSync)(filePath, stripped);
|
|
1560
1667
|
} catch {
|
|
1561
1668
|
}
|
|
@@ -1567,7 +1674,7 @@ var ReplayService = class {
|
|
|
1567
1674
|
if (!(0, import_node_fs2.existsSync)(fernignorePath)) return [];
|
|
1568
1675
|
return (0, import_node_fs2.readFileSync)(fernignorePath, "utf-8").split("\n").map((line) => line.trim()).filter((line) => line && !line.startsWith("#"));
|
|
1569
1676
|
}
|
|
1570
|
-
buildReport(flow, patches, results, options, warnings, rebaseCounts, preRebaseCounts) {
|
|
1677
|
+
buildReport(flow, patches, results, options, warnings, rebaseCounts, preRebaseCounts, patchesReverted) {
|
|
1571
1678
|
const conflictResults = results.filter((r) => r.status === "conflict");
|
|
1572
1679
|
const conflictDetails = conflictResults.map((r) => {
|
|
1573
1680
|
const conflictFiles = r.fileResults?.filter((f) => f.status === "conflict") ?? [];
|
|
@@ -1592,6 +1699,7 @@ var ReplayService = class {
|
|
|
1592
1699
|
patchesRepointed: rebaseCounts && rebaseCounts.repointed > 0 ? rebaseCounts.repointed : void 0,
|
|
1593
1700
|
patchesContentRebased: rebaseCounts && rebaseCounts.contentRebased > 0 ? rebaseCounts.contentRebased : void 0,
|
|
1594
1701
|
patchesKeptAsUserOwned: rebaseCounts && rebaseCounts.keptAsUserOwned > 0 ? rebaseCounts.keptAsUserOwned : void 0,
|
|
1702
|
+
patchesReverted: patchesReverted && patchesReverted > 0 ? patchesReverted : void 0,
|
|
1595
1703
|
patchesConflictResolved: preRebaseCounts && preRebaseCounts.conflictResolved + preRebaseCounts.conflictAbsorbed > 0 ? preRebaseCounts.conflictResolved + preRebaseCounts.conflictAbsorbed : void 0,
|
|
1596
1704
|
patchesRefreshed: preRebaseCounts && preRebaseCounts.contentRefreshed > 0 ? preRebaseCounts.contentRefreshed : void 0,
|
|
1597
1705
|
conflicts: conflictResults.flatMap((r) => r.fileResults?.filter((f) => f.status === "conflict") ?? []),
|
|
@@ -1638,7 +1746,7 @@ var FernignoreMigrator = class {
|
|
|
1638
1746
|
async analyzeMigration() {
|
|
1639
1747
|
const patterns = this.readFernignorePatterns();
|
|
1640
1748
|
const detector = new ReplayDetector(this.git, this.lockManager, this.outputDir);
|
|
1641
|
-
const patches = await detector.detectNewPatches();
|
|
1749
|
+
const { patches } = await detector.detectNewPatches();
|
|
1642
1750
|
const trackedByBoth = [];
|
|
1643
1751
|
const fernignoreOnly = [];
|
|
1644
1752
|
const commitsOnly = [];
|
|
@@ -1763,7 +1871,7 @@ var FernignoreMigrator = class {
|
|
|
1763
1871
|
async migrate() {
|
|
1764
1872
|
const analysis = await this.analyzeMigration();
|
|
1765
1873
|
const detector = new ReplayDetector(this.git, this.lockManager, this.outputDir);
|
|
1766
|
-
const patches = await detector.detectNewPatches();
|
|
1874
|
+
const { patches } = await detector.detectNewPatches();
|
|
1767
1875
|
const warnings = [];
|
|
1768
1876
|
let patchesCreated = 0;
|
|
1769
1877
|
for (const patch of patches) {
|
|
@@ -2180,6 +2288,9 @@ function status(outputDir) {
|
|
|
2180
2288
|
forget,
|
|
2181
2289
|
isGenerationCommit,
|
|
2182
2290
|
isReplayCommit,
|
|
2291
|
+
isRevertCommit,
|
|
2292
|
+
parseRevertedMessage,
|
|
2293
|
+
parseRevertedSha,
|
|
2183
2294
|
reset,
|
|
2184
2295
|
resolve,
|
|
2185
2296
|
status,
|