@lumy-pack/line-lore 0.0.6 → 0.0.7
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.mjs +202 -47
- package/dist/core/ancestry/ancestry.d.ts +14 -1
- package/dist/core/ancestry/index.d.ts +1 -1
- package/dist/core/pr-lookup/index.d.ts +1 -0
- package/dist/core/pr-lookup/pr-lookup.d.ts +18 -2
- package/dist/index.cjs +201 -46
- package/dist/index.mjs +201 -46
- package/dist/platform/github/github-adapter.d.ts +3 -1
- package/dist/platform/gitlab/gitlab-adapter.d.ts +3 -1
- package/dist/types/cache.d.ts +2 -0
- package/dist/types/git.d.ts +2 -0
- package/dist/types/platform.d.ts +3 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -400,6 +400,35 @@ async function findMergeCommit(commitSha, options) {
|
|
|
400
400
|
timeout: remaining
|
|
401
401
|
});
|
|
402
402
|
}
|
|
403
|
+
async function verifyMergeIntroducesCommit(targetSha, mergeResult, options) {
|
|
404
|
+
if (mergeResult.parentShas.length < 2) return true;
|
|
405
|
+
const firstParent = mergeResult.parentShas[0];
|
|
406
|
+
const branchParents = mergeResult.parentShas.slice(1);
|
|
407
|
+
const onMainline = await isAncestor(targetSha, firstParent, options);
|
|
408
|
+
if (onMainline === null) return false;
|
|
409
|
+
if (onMainline) return false;
|
|
410
|
+
for (const branchParent of branchParents) {
|
|
411
|
+
const onBranch = await isAncestor(targetSha, branchParent, options);
|
|
412
|
+
if (onBranch === null) return false;
|
|
413
|
+
if (onBranch) return true;
|
|
414
|
+
}
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
async function isAncestor(commitA, commitB, options) {
|
|
418
|
+
try {
|
|
419
|
+
const result = await gitExec(
|
|
420
|
+
["merge-base", "--is-ancestor", commitA, commitB],
|
|
421
|
+
{
|
|
422
|
+
cwd: options?.cwd,
|
|
423
|
+
timeout: options?.timeout ?? 5e3,
|
|
424
|
+
allowExitCodes: [1]
|
|
425
|
+
}
|
|
426
|
+
);
|
|
427
|
+
return result.exitCode === 0;
|
|
428
|
+
} catch {
|
|
429
|
+
return null;
|
|
430
|
+
}
|
|
431
|
+
}
|
|
403
432
|
async function findMergeCommitWithArgs(commitSha, ref, extraArgs, options) {
|
|
404
433
|
try {
|
|
405
434
|
const result = await gitExec(
|
|
@@ -417,7 +446,25 @@ async function findMergeCommitWithArgs(commitSha, ref, extraArgs, options) {
|
|
|
417
446
|
);
|
|
418
447
|
const lines = (0, import_common_utils9.filter)(result.stdout.trim().split("\n"), import_common_utils9.isTruthy);
|
|
419
448
|
if (lines.length === 0) return null;
|
|
420
|
-
|
|
449
|
+
const candidateCount = Math.min(lines.length, MAX_CANDIDATES);
|
|
450
|
+
let verifiedCount = 0;
|
|
451
|
+
for (let i = 0; i < candidateCount; i++) {
|
|
452
|
+
const candidate = parseMergeLogLine(lines[i]);
|
|
453
|
+
if (!candidate) continue;
|
|
454
|
+
verifiedCount++;
|
|
455
|
+
const verified = await verifyMergeIntroducesCommit(
|
|
456
|
+
commitSha,
|
|
457
|
+
candidate,
|
|
458
|
+
options
|
|
459
|
+
);
|
|
460
|
+
if (verified) return candidate;
|
|
461
|
+
}
|
|
462
|
+
if (verifiedCount > 0 && options?.warnings) {
|
|
463
|
+
options.warnings.push(
|
|
464
|
+
`ancestry: all ${verifiedCount} merge candidate(s) failed verification for ${commitSha.slice(0, 8)}`
|
|
465
|
+
);
|
|
466
|
+
}
|
|
467
|
+
return null;
|
|
421
468
|
} catch {
|
|
422
469
|
return null;
|
|
423
470
|
}
|
|
@@ -439,18 +486,32 @@ function parseMergeLogLine(line) {
|
|
|
439
486
|
const subject = parts.slice(subjectStart).join(" ");
|
|
440
487
|
return { mergeCommitSha, parentShas, subject };
|
|
441
488
|
}
|
|
442
|
-
function
|
|
489
|
+
async function getCommitSubject(sha, options) {
|
|
490
|
+
try {
|
|
491
|
+
const result = await gitExec(["log", "-1", "--format=%s", sha], {
|
|
492
|
+
cwd: options?.cwd,
|
|
493
|
+
timeout: options?.timeout ?? 5e3
|
|
494
|
+
});
|
|
495
|
+
const subject = result.stdout.trim();
|
|
496
|
+
return subject || null;
|
|
497
|
+
} catch {
|
|
498
|
+
return null;
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
function extractPRFromMergeMessage(subject, platform) {
|
|
443
502
|
const ghMatch = /Merge pull request #(\d+)/.exec(subject);
|
|
444
503
|
if (ghMatch) return parseInt(ghMatch[1], 10);
|
|
445
504
|
const squashMatch = /\(#(\d+)\)\s*$/.exec(subject);
|
|
446
505
|
if (squashMatch) return parseInt(squashMatch[1], 10);
|
|
447
|
-
|
|
448
|
-
|
|
506
|
+
if (!platform || platform === "gitlab" || platform === "gitlab-self-hosted") {
|
|
507
|
+
const glMatch = /See merge request\s+\S*!(\d+)\s*$/.exec(subject);
|
|
508
|
+
if (glMatch) return parseInt(glMatch[1], 10);
|
|
509
|
+
}
|
|
449
510
|
const adoMatch = /Merged PR (\d+):/.exec(subject);
|
|
450
511
|
if (adoMatch) return parseInt(adoMatch[1], 10);
|
|
451
512
|
return null;
|
|
452
513
|
}
|
|
453
|
-
var import_common_utils9, DEFAULT_ANCESTRY_TIMEOUT;
|
|
514
|
+
var import_common_utils9, DEFAULT_ANCESTRY_TIMEOUT, MAX_CANDIDATES;
|
|
454
515
|
var init_ancestry = __esm({
|
|
455
516
|
"src/core/ancestry/ancestry.ts"() {
|
|
456
517
|
"use strict";
|
|
@@ -458,6 +519,7 @@ var init_ancestry = __esm({
|
|
|
458
519
|
import_common_utils9 = require("@winglet/common-utils");
|
|
459
520
|
init_executor();
|
|
460
521
|
DEFAULT_ANCESTRY_TIMEOUT = 3e4;
|
|
522
|
+
MAX_CANDIDATES = 10;
|
|
461
523
|
}
|
|
462
524
|
});
|
|
463
525
|
|
|
@@ -588,7 +650,8 @@ function toCachedPR(pr) {
|
|
|
588
650
|
url: pr.url,
|
|
589
651
|
mergeCommit: pr.mergeCommit,
|
|
590
652
|
baseBranch: pr.baseBranch,
|
|
591
|
-
mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : void 0
|
|
653
|
+
mergedAt: pr.mergedAt ? new Date(pr.mergedAt).getTime() : void 0,
|
|
654
|
+
resolvedVia: pr.resolvedVia
|
|
592
655
|
};
|
|
593
656
|
}
|
|
594
657
|
function fromCachedPR(cached) {
|
|
@@ -603,7 +666,9 @@ function fromCachedPR(cached) {
|
|
|
603
666
|
url: cached.url,
|
|
604
667
|
mergeCommit: cached.mergeCommit,
|
|
605
668
|
baseBranch: cached.baseBranch,
|
|
606
|
-
mergedAt
|
|
669
|
+
mergedAt,
|
|
670
|
+
// Preserve original resolvedVia; fallback to url heuristic for legacy cache entries
|
|
671
|
+
resolvedVia: cached.resolvedVia ?? (cached.url ? "api" : "message")
|
|
607
672
|
};
|
|
608
673
|
}
|
|
609
674
|
async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
@@ -614,15 +679,30 @@ async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
|
614
679
|
const cached = await cache.get(commitSha);
|
|
615
680
|
if (cached) return fromCachedPR(cached);
|
|
616
681
|
if (options?.cacheOnly) return null;
|
|
682
|
+
const prSelectOptions = options?.preferredBase ? { preferredBase: options.preferredBase } : void 0;
|
|
683
|
+
if (adapter) {
|
|
684
|
+
const directPR = await adapter.getPRForCommit(commitSha, prSelectOptions);
|
|
685
|
+
if (directPR?.mergedAt) {
|
|
686
|
+
const result = { ...directPR, resolvedVia: "api" };
|
|
687
|
+
await cache.set(commitSha, toCachedPR(result));
|
|
688
|
+
return result;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
617
691
|
let mergeBasedPR = null;
|
|
618
692
|
const mergeResult = await findMergeCommit(commitSha, options);
|
|
619
693
|
if (mergeResult) {
|
|
620
|
-
const prNumber = extractPRFromMergeMessage(
|
|
694
|
+
const prNumber = extractPRFromMergeMessage(
|
|
695
|
+
mergeResult.subject,
|
|
696
|
+
options?.platform
|
|
697
|
+
);
|
|
621
698
|
if (prNumber) {
|
|
622
699
|
if (adapter) {
|
|
623
|
-
const prInfo = await adapter.getPRForCommit(
|
|
700
|
+
const prInfo = await adapter.getPRForCommit(
|
|
701
|
+
mergeResult.mergeCommitSha,
|
|
702
|
+
prSelectOptions
|
|
703
|
+
);
|
|
624
704
|
if (prInfo?.mergedAt) {
|
|
625
|
-
mergeBasedPR = prInfo;
|
|
705
|
+
mergeBasedPR = { ...prInfo, resolvedVia: "ancestry" };
|
|
626
706
|
}
|
|
627
707
|
}
|
|
628
708
|
if (!mergeBasedPR) {
|
|
@@ -632,7 +712,8 @@ async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
|
632
712
|
author: "",
|
|
633
713
|
url: "",
|
|
634
714
|
mergeCommit: mergeResult.mergeCommitSha,
|
|
635
|
-
baseBranch: ""
|
|
715
|
+
baseBranch: "",
|
|
716
|
+
resolvedVia: "ancestry"
|
|
636
717
|
};
|
|
637
718
|
}
|
|
638
719
|
if (!options?.deep || mergeBasedPR.mergedAt) {
|
|
@@ -645,11 +726,24 @@ async function lookupPR(commitSha, adapter, options, _recursionDepth = 0) {
|
|
|
645
726
|
await cache.set(commitSha, toCachedPR(mergeBasedPR));
|
|
646
727
|
return mergeBasedPR;
|
|
647
728
|
}
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
729
|
+
const commitSubject = await getCommitSubject(commitSha, options);
|
|
730
|
+
if (commitSubject) {
|
|
731
|
+
const directPrNumber = extractPRFromMergeMessage(
|
|
732
|
+
commitSubject,
|
|
733
|
+
options?.platform
|
|
734
|
+
);
|
|
735
|
+
if (directPrNumber) {
|
|
736
|
+
const subjectPR = {
|
|
737
|
+
number: directPrNumber,
|
|
738
|
+
title: commitSubject,
|
|
739
|
+
author: "",
|
|
740
|
+
url: "",
|
|
741
|
+
mergeCommit: commitSha,
|
|
742
|
+
baseBranch: "",
|
|
743
|
+
resolvedVia: "message"
|
|
744
|
+
};
|
|
745
|
+
await cache.set(commitSha, toCachedPR(subjectPR));
|
|
746
|
+
return subjectPR;
|
|
653
747
|
}
|
|
654
748
|
}
|
|
655
749
|
if (!options?.skipPatchIdScan && _recursionDepth < MAX_RECURSION_DEPTH) {
|
|
@@ -721,6 +815,7 @@ init_errors();
|
|
|
721
815
|
// src/core/core.ts
|
|
722
816
|
init_cjs_shims();
|
|
723
817
|
var import_node_crypto2 = require("crypto");
|
|
818
|
+
var import_node_path2 = require("path");
|
|
724
819
|
var import_common_utils11 = require("@winglet/common-utils");
|
|
725
820
|
|
|
726
821
|
// src/ast/index.ts
|
|
@@ -1004,7 +1099,7 @@ async function checkGitHealth(options) {
|
|
|
1004
1099
|
const cloneStatus = await checkCloneStatus({ cwd: options?.cwd });
|
|
1005
1100
|
if (cloneStatus.partialClone) {
|
|
1006
1101
|
hints.push(
|
|
1007
|
-
"Partial clone detected. Patch-ID scan (Strategy
|
|
1102
|
+
"Partial clone detected. Patch-ID scan (Strategy 5) will be skipped to avoid blob downloads."
|
|
1008
1103
|
);
|
|
1009
1104
|
}
|
|
1010
1105
|
if (cloneStatus.shallow) {
|
|
@@ -1120,7 +1215,7 @@ var GitHubAdapter = class {
|
|
|
1120
1215
|
return { authenticated: false, hostname: this.hostname };
|
|
1121
1216
|
}
|
|
1122
1217
|
}
|
|
1123
|
-
async getPRForCommit(sha) {
|
|
1218
|
+
async getPRForCommit(sha, options) {
|
|
1124
1219
|
if (this.scheduler.isRateLimited()) return null;
|
|
1125
1220
|
try {
|
|
1126
1221
|
const result = await shellExec(
|
|
@@ -1137,18 +1232,20 @@ var GitHubAdapter = class {
|
|
|
1137
1232
|
);
|
|
1138
1233
|
const prs = JSON.parse(result.stdout);
|
|
1139
1234
|
if (!(0, import_common_utils3.isArray)(prs) || prs.length === 0) return null;
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1235
|
+
let data = prs[0];
|
|
1236
|
+
if (options?.preferredBase) {
|
|
1237
|
+
const preferred = prs.find(
|
|
1238
|
+
(pr) => pr.base === options.preferredBase
|
|
1239
|
+
);
|
|
1240
|
+
if (preferred) data = preferred;
|
|
1241
|
+
}
|
|
1145
1242
|
return {
|
|
1146
1243
|
number: data.number,
|
|
1147
1244
|
title: data.title ?? "",
|
|
1148
1245
|
author: data.user ?? "",
|
|
1149
1246
|
url: data.html_url ?? "",
|
|
1150
1247
|
mergeCommit: data.merge_commit_sha ?? sha,
|
|
1151
|
-
baseBranch: data.base ??
|
|
1248
|
+
baseBranch: data.base ?? "",
|
|
1152
1249
|
mergedAt: data.merged_at
|
|
1153
1250
|
};
|
|
1154
1251
|
} catch {
|
|
@@ -1330,7 +1427,7 @@ var GitLabAdapter = class {
|
|
|
1330
1427
|
return { authenticated: false, hostname: this.hostname };
|
|
1331
1428
|
}
|
|
1332
1429
|
}
|
|
1333
|
-
async getPRForCommit(sha) {
|
|
1430
|
+
async getPRForCommit(sha, options) {
|
|
1334
1431
|
if (this.scheduler.isRateLimited()) return null;
|
|
1335
1432
|
try {
|
|
1336
1433
|
const result = await shellExec(
|
|
@@ -1354,18 +1451,20 @@ var GitLabAdapter = class {
|
|
|
1354
1451
|
return aTime - bTime;
|
|
1355
1452
|
});
|
|
1356
1453
|
if (mergedMRs.length === 0) return null;
|
|
1357
|
-
|
|
1358
|
-
|
|
1359
|
-
|
|
1360
|
-
|
|
1361
|
-
|
|
1454
|
+
let mr = mergedMRs[0];
|
|
1455
|
+
if (options?.preferredBase) {
|
|
1456
|
+
const preferred = mergedMRs.find(
|
|
1457
|
+
(m) => m.target_branch === options.preferredBase
|
|
1458
|
+
);
|
|
1459
|
+
if (preferred) mr = preferred;
|
|
1460
|
+
}
|
|
1362
1461
|
return {
|
|
1363
1462
|
number: mr.iid,
|
|
1364
1463
|
title: mr.title ?? "",
|
|
1365
1464
|
author: mr.author?.username ?? "",
|
|
1366
1465
|
url: mr.web_url ?? "",
|
|
1367
1466
|
mergeCommit: mr.merge_commit_sha ?? sha,
|
|
1368
|
-
baseBranch: mr.target_branch ??
|
|
1467
|
+
baseBranch: mr.target_branch ?? "",
|
|
1369
1468
|
mergedAt: mr.merged_at
|
|
1370
1469
|
};
|
|
1371
1470
|
} catch {
|
|
@@ -2173,6 +2272,28 @@ async function traverse(adapter, type, number, depth, maxDepth, nodes, edges, vi
|
|
|
2173
2272
|
|
|
2174
2273
|
// src/core/core.ts
|
|
2175
2274
|
init_pr_lookup2();
|
|
2275
|
+
function resolvedViaToTrackingMethod(resolvedVia) {
|
|
2276
|
+
switch (resolvedVia) {
|
|
2277
|
+
case "api":
|
|
2278
|
+
return "api";
|
|
2279
|
+
case "ancestry":
|
|
2280
|
+
return "ancestry-path";
|
|
2281
|
+
case "message":
|
|
2282
|
+
return "message-parse";
|
|
2283
|
+
case "patch-id":
|
|
2284
|
+
return "patch-id";
|
|
2285
|
+
}
|
|
2286
|
+
}
|
|
2287
|
+
function resolvedViaToConfidence(resolvedVia) {
|
|
2288
|
+
switch (resolvedVia) {
|
|
2289
|
+
case "api":
|
|
2290
|
+
case "ancestry":
|
|
2291
|
+
return "exact";
|
|
2292
|
+
case "message":
|
|
2293
|
+
case "patch-id":
|
|
2294
|
+
return "heuristic";
|
|
2295
|
+
}
|
|
2296
|
+
}
|
|
2176
2297
|
function computeFeatureFlags(operatingLevel, options) {
|
|
2177
2298
|
return {
|
|
2178
2299
|
astDiff: isAstAvailable() && !options.noAst,
|
|
@@ -2190,6 +2311,22 @@ async function resolveRepoIdentity(cwd) {
|
|
|
2190
2311
|
return { host: "_local", owner: "_", repo: "_unknown" };
|
|
2191
2312
|
}
|
|
2192
2313
|
}
|
|
2314
|
+
async function resolveFileContext(file, cwd) {
|
|
2315
|
+
if (cwd || !(0, import_node_path2.isAbsolute)(file)) return { file, cwd };
|
|
2316
|
+
const fileDir = (0, import_node_path2.dirname)(file);
|
|
2317
|
+
try {
|
|
2318
|
+
const result = await gitExec(["rev-parse", "--show-toplevel"], {
|
|
2319
|
+
cwd: fileDir
|
|
2320
|
+
});
|
|
2321
|
+
const repoRoot = result.stdout.trim();
|
|
2322
|
+
return {
|
|
2323
|
+
file: (0, import_node_path2.relative)(repoRoot, file),
|
|
2324
|
+
cwd: repoRoot
|
|
2325
|
+
};
|
|
2326
|
+
} catch {
|
|
2327
|
+
return { file, cwd };
|
|
2328
|
+
}
|
|
2329
|
+
}
|
|
2193
2330
|
async function detectPlatform2(options) {
|
|
2194
2331
|
const warnings = [];
|
|
2195
2332
|
let adapter = null;
|
|
@@ -2236,7 +2373,7 @@ async function runBlameAndAuth(adapter, options, execOptions) {
|
|
|
2236
2373
|
}
|
|
2237
2374
|
return { analyzed: blameResult.value, operatingLevel, warnings };
|
|
2238
2375
|
}
|
|
2239
|
-
async function processEntry(entry, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan) {
|
|
2376
|
+
async function processEntry(entry, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan, preferredBase) {
|
|
2240
2377
|
const nodes = [];
|
|
2241
2378
|
const commitNode = {
|
|
2242
2379
|
type: entry.isCosmetic ? "cosmetic_commit" : "original_commit",
|
|
@@ -2270,14 +2407,16 @@ async function processEntry(entry, featureFlags, adapter, options, execOptions,
|
|
|
2270
2407
|
cacheOnly: options.cacheOnly,
|
|
2271
2408
|
deep: featureFlags.deepTrace,
|
|
2272
2409
|
repoId,
|
|
2273
|
-
skipPatchIdScan
|
|
2410
|
+
skipPatchIdScan,
|
|
2411
|
+
preferredBase,
|
|
2412
|
+
platform: adapter?.platform
|
|
2274
2413
|
});
|
|
2275
2414
|
if (prInfo) {
|
|
2276
2415
|
nodes.push({
|
|
2277
2416
|
type: "pull_request",
|
|
2278
2417
|
sha: prInfo.mergeCommit,
|
|
2279
|
-
trackingMethod: prInfo.
|
|
2280
|
-
confidence: prInfo.
|
|
2418
|
+
trackingMethod: resolvedViaToTrackingMethod(prInfo.resolvedVia),
|
|
2419
|
+
confidence: resolvedViaToConfidence(prInfo.resolvedVia),
|
|
2281
2420
|
prNumber: prInfo.number,
|
|
2282
2421
|
prUrl: prInfo.url || void 0,
|
|
2283
2422
|
prTitle: prInfo.title || void 0,
|
|
@@ -2287,7 +2426,7 @@ async function processEntry(entry, featureFlags, adapter, options, execOptions,
|
|
|
2287
2426
|
}
|
|
2288
2427
|
return nodes;
|
|
2289
2428
|
}
|
|
2290
|
-
async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan) {
|
|
2429
|
+
async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOptions, repoId, skipPatchIdScan, preferredBase) {
|
|
2291
2430
|
const results = await Promise.allSettled(
|
|
2292
2431
|
(0, import_common_utils11.map)(
|
|
2293
2432
|
analyzed,
|
|
@@ -2298,7 +2437,8 @@ async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOpt
|
|
|
2298
2437
|
options,
|
|
2299
2438
|
execOptions,
|
|
2300
2439
|
repoId,
|
|
2301
|
-
skipPatchIdScan
|
|
2440
|
+
skipPatchIdScan,
|
|
2441
|
+
preferredBase
|
|
2302
2442
|
)
|
|
2303
2443
|
)
|
|
2304
2444
|
);
|
|
@@ -2306,13 +2446,15 @@ async function buildTraceNodes(analyzed, featureFlags, adapter, options, execOpt
|
|
|
2306
2446
|
}
|
|
2307
2447
|
var legacyCacheCleaned = false;
|
|
2308
2448
|
async function trace(options) {
|
|
2309
|
-
const
|
|
2449
|
+
const { file, cwd } = await resolveFileContext(options.file, options.cwd);
|
|
2450
|
+
const warnings = [];
|
|
2451
|
+
const execOptions = { cwd, warnings };
|
|
2310
2452
|
if (!legacyCacheCleaned) {
|
|
2311
2453
|
legacyCacheCleaned = true;
|
|
2312
2454
|
cleanupLegacyCache().catch(() => {
|
|
2313
2455
|
});
|
|
2314
2456
|
}
|
|
2315
|
-
const platform = await detectPlatform2(options);
|
|
2457
|
+
const platform = await detectPlatform2({ ...options, cwd });
|
|
2316
2458
|
let repoId;
|
|
2317
2459
|
if (platform.remote) {
|
|
2318
2460
|
repoId = {
|
|
@@ -2321,15 +2463,15 @@ async function trace(options) {
|
|
|
2321
2463
|
repo: platform.remote.repo
|
|
2322
2464
|
};
|
|
2323
2465
|
} else {
|
|
2324
|
-
repoId = await resolveRepoIdentity(
|
|
2466
|
+
repoId = await resolveRepoIdentity(cwd);
|
|
2325
2467
|
}
|
|
2326
2468
|
const blameAuth = await runBlameAndAuth(
|
|
2327
2469
|
platform.adapter,
|
|
2328
|
-
options,
|
|
2470
|
+
{ ...options, file, cwd },
|
|
2329
2471
|
execOptions
|
|
2330
2472
|
);
|
|
2331
2473
|
const operatingLevel = blameAuth.operatingLevel || platform.operatingLevel;
|
|
2332
|
-
|
|
2474
|
+
warnings.push(...platform.warnings, ...blameAuth.warnings);
|
|
2333
2475
|
if (options.cacheOnly && options.noCache) {
|
|
2334
2476
|
warnings.push(
|
|
2335
2477
|
"Both cacheOnly and noCache are set. cacheOnly takes precedence \u2014 cache reads are enabled."
|
|
@@ -2338,13 +2480,13 @@ async function trace(options) {
|
|
|
2338
2480
|
const featureFlags = computeFeatureFlags(operatingLevel, options);
|
|
2339
2481
|
let cloneStatus = { partialClone: false, shallow: false };
|
|
2340
2482
|
try {
|
|
2341
|
-
const result = await checkCloneStatus({ cwd
|
|
2483
|
+
const result = await checkCloneStatus({ cwd });
|
|
2342
2484
|
if (result) cloneStatus = result;
|
|
2343
2485
|
} catch {
|
|
2344
2486
|
}
|
|
2345
2487
|
if (cloneStatus.partialClone) {
|
|
2346
2488
|
warnings.push(
|
|
2347
|
-
"Partial clone detected. Patch-ID scan (Strategy
|
|
2489
|
+
"Partial clone detected. Patch-ID scan (Strategy 5) will be skipped to avoid blob downloads."
|
|
2348
2490
|
);
|
|
2349
2491
|
}
|
|
2350
2492
|
if (cloneStatus.shallow) {
|
|
@@ -2352,14 +2494,27 @@ async function trace(options) {
|
|
|
2352
2494
|
"Shallow repository detected. Ancestry-path results may be incomplete."
|
|
2353
2495
|
);
|
|
2354
2496
|
}
|
|
2497
|
+
let preferredBase;
|
|
2498
|
+
try {
|
|
2499
|
+
const branchResult = await gitExec(
|
|
2500
|
+
["rev-parse", "--abbrev-ref", "HEAD"],
|
|
2501
|
+
execOptions
|
|
2502
|
+
);
|
|
2503
|
+
const branch = branchResult.stdout.trim();
|
|
2504
|
+
if (branch && branch !== "HEAD") {
|
|
2505
|
+
preferredBase = branch;
|
|
2506
|
+
}
|
|
2507
|
+
} catch {
|
|
2508
|
+
}
|
|
2355
2509
|
const nodes = await buildTraceNodes(
|
|
2356
2510
|
blameAuth.analyzed,
|
|
2357
2511
|
featureFlags,
|
|
2358
2512
|
platform.adapter,
|
|
2359
|
-
options,
|
|
2513
|
+
{ ...options, file, cwd },
|
|
2360
2514
|
execOptions,
|
|
2361
2515
|
repoId,
|
|
2362
|
-
cloneStatus.partialClone || void 0
|
|
2516
|
+
cloneStatus.partialClone || void 0,
|
|
2517
|
+
preferredBase
|
|
2363
2518
|
);
|
|
2364
2519
|
return { nodes, operatingLevel, featureFlags, warnings };
|
|
2365
2520
|
}
|