perttool 0.10.2 → 0.10.4
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/CHANGELOG.md +25 -1
- package/README.md +12 -8
- package/dist/application/target-project-history.d.ts.map +1 -1
- package/dist/application/target-project-history.js +42 -1
- package/dist/application/target-project-history.js.map +1 -1
- package/dist/application/target-velocity-observation.d.ts.map +1 -1
- package/dist/application/target-velocity-observation.js +28 -1
- package/dist/application/target-velocity-observation.js.map +1 -1
- package/dist/cli.js +8 -0
- package/dist/cli.js.map +1 -1
- package/dist/command/actuals-discovery.d.ts.map +1 -1
- package/dist/command/actuals-discovery.js +8 -0
- package/dist/command/actuals-discovery.js.map +1 -1
- package/dist/conversion/mermaid.d.ts.map +1 -1
- package/dist/conversion/mermaid.js +8 -2
- package/dist/conversion/mermaid.js.map +1 -1
- package/dist/formatter/source-formatter.js +2 -2
- package/dist/formatter/source-formatter.js.map +1 -1
- package/dist/help/assurance-guide.js +1 -1
- package/dist/help/assurance-guide.js.map +1 -1
- package/dist/history/git-probe.d.ts +18 -1
- package/dist/history/git-probe.d.ts.map +1 -1
- package/dist/history/git-probe.js +233 -68
- package/dist/history/git-probe.js.map +1 -1
- package/dist/history/project-history.d.ts +16 -1
- package/dist/history/project-history.d.ts.map +1 -1
- package/dist/history/project-history.js +119 -8
- package/dist/history/project-history.js.map +1 -1
- package/dist/history/velocity-observation.d.ts.map +1 -1
- package/dist/history/velocity-observation.js +3 -5
- package/dist/history/velocity-observation.js.map +1 -1
- package/dist/model/exact-duration-source.d.ts +7 -0
- package/dist/model/exact-duration-source.d.ts.map +1 -1
- package/dist/model/exact-duration-source.js +18 -2
- package/dist/model/exact-duration-source.js.map +1 -1
- package/dist/model/exact-velocity-source.d.ts +13 -0
- package/dist/model/exact-velocity-source.d.ts.map +1 -0
- package/dist/model/exact-velocity-source.js +38 -0
- package/dist/model/exact-velocity-source.js.map +1 -0
- package/dist/model/syntax.d.ts +2 -2
- package/dist/model/syntax.d.ts.map +1 -1
- package/dist/parser/document-parser.d.ts.map +1 -1
- package/dist/parser/document-parser.js +12 -29
- package/dist/parser/document-parser.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +1 -1
- package/schemas/Perttool.Common.v1.schema.json +40 -2
|
@@ -21,9 +21,21 @@ const availabilityOrder = new Map([
|
|
|
21
21
|
["ambiguous_path", 4],
|
|
22
22
|
["shallow_boundary", 5],
|
|
23
23
|
["unsupported_rename", 6],
|
|
24
|
-
["
|
|
25
|
-
["
|
|
24
|
+
["provenance_unavailable", 7],
|
|
25
|
+
["head_changed", 8],
|
|
26
|
+
["target_changed", 9],
|
|
26
27
|
]);
|
|
28
|
+
function emptyProvenance(requestedMode) {
|
|
29
|
+
return Object.freeze({
|
|
30
|
+
modelVersion: 1,
|
|
31
|
+
requestedMode,
|
|
32
|
+
effectiveMode: "automatic",
|
|
33
|
+
overrideApplied: false,
|
|
34
|
+
rootCommitId: null,
|
|
35
|
+
rootSourceDigest: null,
|
|
36
|
+
excludedPredecessors: Object.freeze([]),
|
|
37
|
+
});
|
|
38
|
+
}
|
|
27
39
|
function errorCode(error) {
|
|
28
40
|
return typeof error === "object" && error !== null && "code" in error
|
|
29
41
|
? String(error.code)
|
|
@@ -200,29 +212,197 @@ function availability(causes) {
|
|
|
200
212
|
return (left.commitId ?? "").localeCompare(right.commitId ?? "", "en");
|
|
201
213
|
}));
|
|
202
214
|
}
|
|
203
|
-
function unavailable(requestedRevision, cause, fields
|
|
215
|
+
function unavailable(requestedRevision, cause, fields) {
|
|
204
216
|
return {
|
|
205
217
|
ok: true,
|
|
206
218
|
modelVersion: GIT_HISTORY_PROBE_MODEL_VERSION,
|
|
207
219
|
status: "unavailable",
|
|
208
220
|
traversal: "first_parent",
|
|
209
|
-
objectFormat: fields.objectFormat
|
|
210
|
-
repositorySnapshotId: fields.repositorySnapshotId
|
|
211
|
-
repositoryRelativePath: fields.repositoryRelativePath
|
|
221
|
+
objectFormat: nullable(fields.objectFormat),
|
|
222
|
+
repositorySnapshotId: nullable(fields.repositorySnapshotId),
|
|
223
|
+
repositoryRelativePath: nullable(fields.repositoryRelativePath),
|
|
212
224
|
requestedRevision,
|
|
213
|
-
resolvedRevision: fields.resolvedRevision
|
|
214
|
-
headCommitId: fields.headCommitId
|
|
215
|
-
currentSourceDigest: fields.currentSourceDigest
|
|
216
|
-
selectedSourceDigest: fields.selectedSourceDigest
|
|
217
|
-
inspectedCommitIds: fields.inspectedCommitIds
|
|
218
|
-
snapshots: fields.snapshots
|
|
225
|
+
resolvedRevision: nullable(fields.resolvedRevision),
|
|
226
|
+
headCommitId: nullable(fields.headCommitId),
|
|
227
|
+
currentSourceDigest: nullable(fields.currentSourceDigest),
|
|
228
|
+
selectedSourceDigest: nullable(fields.selectedSourceDigest),
|
|
229
|
+
inspectedCommitIds: arrayValue(fields.inspectedCommitIds),
|
|
230
|
+
snapshots: arrayValue(fields.snapshots),
|
|
219
231
|
availability: availability([{ cause, commitId: null }]),
|
|
232
|
+
provenance: fields.provenance ?? emptyProvenance("automatic"),
|
|
220
233
|
};
|
|
221
234
|
}
|
|
235
|
+
function nullable(value) {
|
|
236
|
+
return value === undefined ? null : value;
|
|
237
|
+
}
|
|
238
|
+
function arrayValue(value) {
|
|
239
|
+
return value === undefined ? [] : value;
|
|
240
|
+
}
|
|
222
241
|
function commitId(value, objectFormat) {
|
|
223
242
|
const length = objectFormat === "sha1" ? 40 : 64;
|
|
224
243
|
return new RegExp(`^[0-9a-f]{${length}}$`).test(value);
|
|
225
244
|
}
|
|
245
|
+
function decodeGitPath(value) {
|
|
246
|
+
try {
|
|
247
|
+
const path = new TextDecoder("utf-8", { fatal: true }).decode(value);
|
|
248
|
+
return path === "" || /[\u0000\r\n]/.test(path) ? null : path;
|
|
249
|
+
}
|
|
250
|
+
catch {
|
|
251
|
+
return null;
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
function renameCandidates(value, selectedPath) {
|
|
255
|
+
if (value.length === 0)
|
|
256
|
+
return Object.freeze([]);
|
|
257
|
+
const fields = value.subarray(0, value.at(-1) === 0 ? -1 : value.length)
|
|
258
|
+
.toString("latin1").split("\u0000").map((field) => Buffer.from(field, "latin1"));
|
|
259
|
+
const result = [];
|
|
260
|
+
for (let index = 0; index < fields.length;) {
|
|
261
|
+
const record = consumeDiffRecord(fields, index, selectedPath);
|
|
262
|
+
if (record === null)
|
|
263
|
+
return null;
|
|
264
|
+
index = record.nextIndex;
|
|
265
|
+
if (record.candidate !== null)
|
|
266
|
+
result.push(record.candidate);
|
|
267
|
+
}
|
|
268
|
+
return Object.freeze(result);
|
|
269
|
+
}
|
|
270
|
+
function consumeDiffRecord(fields, index, selectedPath) {
|
|
271
|
+
const statusField = fields[index];
|
|
272
|
+
if (statusField === undefined)
|
|
273
|
+
return null;
|
|
274
|
+
const status = statusField.toString("ascii");
|
|
275
|
+
if (!/^[A-Z][0-9]*$/.test(status))
|
|
276
|
+
return null;
|
|
277
|
+
if (!status.startsWith("R") && !status.startsWith("C")) {
|
|
278
|
+
const path = fields[index + 1];
|
|
279
|
+
return path !== undefined && decodeGitPath(path) !== null
|
|
280
|
+
? { nextIndex: index + 2, candidate: null }
|
|
281
|
+
: null;
|
|
282
|
+
}
|
|
283
|
+
const oldPath = fields[index + 1];
|
|
284
|
+
const newPath = fields[index + 2];
|
|
285
|
+
if (oldPath === undefined || newPath === undefined)
|
|
286
|
+
return null;
|
|
287
|
+
const oldText = decodeGitPath(oldPath);
|
|
288
|
+
const newText = decodeGitPath(newPath);
|
|
289
|
+
if (oldText === null || newText === null)
|
|
290
|
+
return null;
|
|
291
|
+
const candidate = status.startsWith("R") && newText === selectedPath
|
|
292
|
+
? { oldPath: oldText, newPath: newText }
|
|
293
|
+
: null;
|
|
294
|
+
return { nextIndex: index + 3, candidate };
|
|
295
|
+
}
|
|
296
|
+
function collectHistorySnapshots(request) {
|
|
297
|
+
const snapshots = [];
|
|
298
|
+
for (const inspectedCommitId of request.inspectedCommitIds) {
|
|
299
|
+
const metadataCommand = runGit(request.executable, request.repositoryRoot, "commit_metadata", ["show", "-s", "--format=%P%x00%cI", inspectedCommitId]);
|
|
300
|
+
if (!metadataCommand.ok) {
|
|
301
|
+
return metadataCommand.kind === "failure"
|
|
302
|
+
? metadataCommand.failure
|
|
303
|
+
: commandFailure("commit_metadata");
|
|
304
|
+
}
|
|
305
|
+
const metadataText = stdoutText(metadataCommand, "commit_metadata");
|
|
306
|
+
if (typeof metadataText !== "string")
|
|
307
|
+
return metadataText;
|
|
308
|
+
const metadata = parseGitCommitMetadata(metadataText, request.objectFormat);
|
|
309
|
+
if (metadata === null)
|
|
310
|
+
return malformed("commit_metadata");
|
|
311
|
+
const exists = runGit(request.executable, request.repositoryRoot, "snapshot_exists", ["ls-tree", "-z", "--name-only", inspectedCommitId, "--", request.relativePath]);
|
|
312
|
+
if (!exists.ok) {
|
|
313
|
+
return exists.kind === "failure"
|
|
314
|
+
? exists.failure
|
|
315
|
+
: commandFailure("snapshot_exists");
|
|
316
|
+
}
|
|
317
|
+
let source = null;
|
|
318
|
+
let sourceDigest = null;
|
|
319
|
+
if (exists.stdout.length > 0) {
|
|
320
|
+
if (!exists.stdout.equals(Buffer.from(`${request.relativePath}\0`, "utf8"))) {
|
|
321
|
+
return malformed("snapshot_exists");
|
|
322
|
+
}
|
|
323
|
+
const sourceCommand = runGit(request.executable, request.repositoryRoot, "snapshot_source", ["cat-file", "blob", `${inspectedCommitId}:${request.relativePath}`]);
|
|
324
|
+
if (!sourceCommand.ok) {
|
|
325
|
+
return sourceCommand.kind === "failure"
|
|
326
|
+
? sourceCommand.failure
|
|
327
|
+
: commandFailure("snapshot_source");
|
|
328
|
+
}
|
|
329
|
+
source = new Uint8Array(sourceCommand.stdout);
|
|
330
|
+
sourceDigest = digestDocumentBytes(source);
|
|
331
|
+
}
|
|
332
|
+
snapshots.push({
|
|
333
|
+
repositorySnapshotId: request.repositorySnapshotId,
|
|
334
|
+
relativePath: request.relativePath,
|
|
335
|
+
commitId: inspectedCommitId,
|
|
336
|
+
parentCommitIds: metadata.parentCommitIds,
|
|
337
|
+
recordedAt: metadata.recordedAt,
|
|
338
|
+
sourceDigest,
|
|
339
|
+
source,
|
|
340
|
+
});
|
|
341
|
+
}
|
|
342
|
+
return { ok: true, snapshots: Object.freeze(snapshots) };
|
|
343
|
+
}
|
|
344
|
+
function treeBlobId(value, expectedPath, objectFormat) {
|
|
345
|
+
const fields = value.subarray(0, value.at(-1) === 0 ? -1 : value.length)
|
|
346
|
+
.toString("latin1").split("\u0000").map((field) => Buffer.from(field, "latin1"));
|
|
347
|
+
if (fields.length !== 1)
|
|
348
|
+
return null;
|
|
349
|
+
const separator = fields[0].indexOf(0x09);
|
|
350
|
+
if (separator < 0)
|
|
351
|
+
return null;
|
|
352
|
+
const metadata = fields[0].subarray(0, separator).toString("ascii");
|
|
353
|
+
const path = decodeGitPath(fields[0].subarray(separator + 1));
|
|
354
|
+
const match = /^[0-7]{6} blob ([0-9a-f]+)$/.exec(metadata);
|
|
355
|
+
return path === expectedPath && match !== null && commitId(match[1], objectFormat)
|
|
356
|
+
? match[1]
|
|
357
|
+
: null;
|
|
358
|
+
}
|
|
359
|
+
function probeNewRootProvenance(executable, repositoryRoot, relativePath, objectFormat, snapshots) {
|
|
360
|
+
const root = snapshots[0];
|
|
361
|
+
if (root === undefined || root.source === null || root.sourceDigest === null) {
|
|
362
|
+
return null;
|
|
363
|
+
}
|
|
364
|
+
if (root.parentCommitIds.length !== 1)
|
|
365
|
+
return null;
|
|
366
|
+
const parentCommitId = root.parentCommitIds[0];
|
|
367
|
+
const diff = runGit(executable, repositoryRoot, "provenance_root_diff", [
|
|
368
|
+
"diff-tree", "-r", "--name-status", "-z", "-M",
|
|
369
|
+
parentCommitId, root.commitId,
|
|
370
|
+
]);
|
|
371
|
+
if (!diff.ok)
|
|
372
|
+
return null;
|
|
373
|
+
const candidates = renameCandidates(diff.stdout, relativePath);
|
|
374
|
+
if (candidates === null || candidates.length !== 1)
|
|
375
|
+
return null;
|
|
376
|
+
const predecessorPath = candidates[0].oldPath;
|
|
377
|
+
const tree = runGit(executable, repositoryRoot, "provenance_predecessor_tree", [
|
|
378
|
+
"ls-tree", "-z", parentCommitId, "--", predecessorPath,
|
|
379
|
+
]);
|
|
380
|
+
if (!tree.ok)
|
|
381
|
+
return null;
|
|
382
|
+
const blobId = treeBlobId(tree.stdout, predecessorPath, objectFormat);
|
|
383
|
+
if (blobId === null)
|
|
384
|
+
return null;
|
|
385
|
+
const source = runGit(executable, repositoryRoot, "provenance_predecessor_source", [
|
|
386
|
+
"cat-file", "blob", blobId,
|
|
387
|
+
]);
|
|
388
|
+
if (!source.ok)
|
|
389
|
+
return null;
|
|
390
|
+
const predecessorSource = new Uint8Array(source.stdout);
|
|
391
|
+
return Object.freeze({
|
|
392
|
+
modelVersion: 1,
|
|
393
|
+
requestedMode: "new_root",
|
|
394
|
+
effectiveMode: "new_root",
|
|
395
|
+
overrideApplied: true,
|
|
396
|
+
rootCommitId: root.commitId,
|
|
397
|
+
rootSourceDigest: root.sourceDigest,
|
|
398
|
+
excludedPredecessors: Object.freeze([Object.freeze({
|
|
399
|
+
path: predecessorPath,
|
|
400
|
+
commitId: parentCommitId,
|
|
401
|
+
sourceDigest: digestDocumentBytes(predecessorSource),
|
|
402
|
+
source: predecessorSource,
|
|
403
|
+
})]),
|
|
404
|
+
});
|
|
405
|
+
}
|
|
226
406
|
export function parseGitCommitMetadata(value, objectFormat) {
|
|
227
407
|
const separatorIndex = value.indexOf("\0");
|
|
228
408
|
if (separatorIndex === -1)
|
|
@@ -266,12 +446,16 @@ function sameTarget(left, right) {
|
|
|
266
446
|
}
|
|
267
447
|
export async function probeGitHistory(request, dependencies = {}) {
|
|
268
448
|
const requestedRevision = request.revision ?? "HEAD";
|
|
449
|
+
const requestedProvenanceMode = request.provenanceMode ?? "automatic";
|
|
450
|
+
const initialProvenance = emptyProvenance(requestedProvenanceMode);
|
|
269
451
|
const executable = dependencies.gitExecutable ?? "git";
|
|
270
452
|
const targetPath = resolve(request.targetPath);
|
|
271
453
|
const initialTarget = await captureTarget(targetPath);
|
|
272
454
|
if (!initialTarget.ok) {
|
|
273
455
|
if ("ambiguous" in initialTarget) {
|
|
274
|
-
return unavailable(requestedRevision, "ambiguous_path"
|
|
456
|
+
return unavailable(requestedRevision, "ambiguous_path", {
|
|
457
|
+
provenance: initialProvenance,
|
|
458
|
+
});
|
|
275
459
|
}
|
|
276
460
|
return initialTarget.failure;
|
|
277
461
|
}
|
|
@@ -282,6 +466,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
282
466
|
}
|
|
283
467
|
return unavailable(requestedRevision, "no_repository", {
|
|
284
468
|
currentSourceDigest: initialTarget.capture.digest,
|
|
469
|
+
provenance: initialProvenance,
|
|
285
470
|
});
|
|
286
471
|
}
|
|
287
472
|
const repositoryText = stdoutText(repositoryCommand, "repository_root");
|
|
@@ -298,6 +483,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
298
483
|
if (relativePath === null) {
|
|
299
484
|
return unavailable(requestedRevision, "ambiguous_path", {
|
|
300
485
|
currentSourceDigest: initialTarget.capture.digest,
|
|
486
|
+
provenance: initialProvenance,
|
|
301
487
|
});
|
|
302
488
|
}
|
|
303
489
|
const headCommand = runGit(executable, repositoryRoot, "resolve_head", ["rev-parse", "--verify", "--end-of-options", "HEAD^{commit}"]);
|
|
@@ -307,6 +493,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
307
493
|
return unavailable(requestedRevision, "no_head", {
|
|
308
494
|
repositoryRelativePath: relativePath,
|
|
309
495
|
currentSourceDigest: initialTarget.capture.digest,
|
|
496
|
+
provenance: initialProvenance,
|
|
310
497
|
});
|
|
311
498
|
}
|
|
312
499
|
const formatCommand = runGit(executable, repositoryRoot, "object_format", ["rev-parse", "--show-object-format=storage"]);
|
|
@@ -342,6 +529,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
342
529
|
repositoryRelativePath: relativePath,
|
|
343
530
|
headCommitId: initialHead,
|
|
344
531
|
currentSourceDigest: initialTarget.capture.digest,
|
|
532
|
+
provenance: initialProvenance,
|
|
345
533
|
});
|
|
346
534
|
}
|
|
347
535
|
const revisionText = stdoutText(revisionCommand, "resolve_revision");
|
|
@@ -361,6 +549,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
361
549
|
resolvedRevision,
|
|
362
550
|
headCommitId: initialHead,
|
|
363
551
|
currentSourceDigest: initialTarget.capture.digest,
|
|
552
|
+
provenance: initialProvenance,
|
|
364
553
|
});
|
|
365
554
|
}
|
|
366
555
|
const trackedCommand = runGit(executable, repositoryRoot, "selected_target", [
|
|
@@ -384,6 +573,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
384
573
|
resolvedRevision,
|
|
385
574
|
headCommitId: initialHead,
|
|
386
575
|
currentSourceDigest: initialTarget.capture.digest,
|
|
576
|
+
provenance: initialProvenance,
|
|
387
577
|
});
|
|
388
578
|
}
|
|
389
579
|
if (!trackedCommand.stdout.equals(Buffer.from(`${relativePath}\0`, "utf8"))) {
|
|
@@ -394,6 +584,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
394
584
|
resolvedRevision,
|
|
395
585
|
headCommitId: initialHead,
|
|
396
586
|
currentSourceDigest: initialTarget.capture.digest,
|
|
587
|
+
provenance: initialProvenance,
|
|
397
588
|
});
|
|
398
589
|
}
|
|
399
590
|
const commitsCommand = runGit(executable, repositoryRoot, "first_parent_commits", [
|
|
@@ -420,61 +611,32 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
420
611
|
new Set(inspectedCommitIds).size !== inspectedCommitIds.length) {
|
|
421
612
|
return malformed("first_parent_commits");
|
|
422
613
|
}
|
|
423
|
-
const
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
if (metadata === null)
|
|
441
|
-
return malformed("commit_metadata");
|
|
442
|
-
const existsCommand = runGit(executable, repositoryRoot, "snapshot_exists", [
|
|
443
|
-
"ls-tree",
|
|
444
|
-
"-z",
|
|
445
|
-
"--name-only",
|
|
446
|
-
inspectedCommitId,
|
|
447
|
-
"--",
|
|
448
|
-
relativePath,
|
|
449
|
-
]);
|
|
450
|
-
if (!existsCommand.ok) {
|
|
451
|
-
return existsCommand.kind === "failure"
|
|
452
|
-
? existsCommand.failure
|
|
453
|
-
: commandFailure("snapshot_exists");
|
|
454
|
-
}
|
|
455
|
-
let source = null;
|
|
456
|
-
let sourceDigest = null;
|
|
457
|
-
if (existsCommand.stdout.length > 0) {
|
|
458
|
-
if (!existsCommand.stdout.equals(Buffer.from(`${relativePath}\0`, "utf8"))) {
|
|
459
|
-
return malformed("snapshot_exists");
|
|
460
|
-
}
|
|
461
|
-
const sourceCommand = runGit(executable, repositoryRoot, "snapshot_source", ["cat-file", "blob", `${inspectedCommitId}:${relativePath}`]);
|
|
462
|
-
if (!sourceCommand.ok) {
|
|
463
|
-
return sourceCommand.kind === "failure"
|
|
464
|
-
? sourceCommand.failure
|
|
465
|
-
: commandFailure("snapshot_source");
|
|
466
|
-
}
|
|
467
|
-
source = new Uint8Array(sourceCommand.stdout);
|
|
468
|
-
sourceDigest = digestDocumentBytes(source);
|
|
469
|
-
}
|
|
470
|
-
snapshots.push({
|
|
614
|
+
const snapshotCollection = collectHistorySnapshots({
|
|
615
|
+
executable,
|
|
616
|
+
repositoryRoot,
|
|
617
|
+
repositorySnapshotId,
|
|
618
|
+
relativePath,
|
|
619
|
+
objectFormat,
|
|
620
|
+
inspectedCommitIds,
|
|
621
|
+
});
|
|
622
|
+
if (!snapshotCollection.ok)
|
|
623
|
+
return snapshotCollection;
|
|
624
|
+
const snapshots = snapshotCollection.snapshots;
|
|
625
|
+
const provenance = requestedProvenanceMode === "new_root"
|
|
626
|
+
? probeNewRootProvenance(executable, repositoryRoot, relativePath, objectFormat, snapshots)
|
|
627
|
+
: initialProvenance;
|
|
628
|
+
if (provenance === null) {
|
|
629
|
+
return unavailable(requestedRevision, "provenance_unavailable", {
|
|
630
|
+
objectFormat,
|
|
471
631
|
repositorySnapshotId,
|
|
472
|
-
relativePath,
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
sourceDigest,
|
|
477
|
-
|
|
632
|
+
repositoryRelativePath: relativePath,
|
|
633
|
+
resolvedRevision,
|
|
634
|
+
headCommitId: initialHead,
|
|
635
|
+
currentSourceDigest: initialTarget.capture.digest,
|
|
636
|
+
selectedSourceDigest: snapshots.at(-1)?.sourceDigest ?? null,
|
|
637
|
+
inspectedCommitIds,
|
|
638
|
+
snapshots,
|
|
639
|
+
provenance: initialProvenance,
|
|
478
640
|
});
|
|
479
641
|
}
|
|
480
642
|
const renameCommand = runGit(executable, repositoryRoot, "rename_detection", [
|
|
@@ -523,6 +685,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
523
685
|
selectedSourceDigest: snapshots.at(-1)?.sourceDigest ?? null,
|
|
524
686
|
inspectedCommitIds,
|
|
525
687
|
snapshots,
|
|
688
|
+
provenance,
|
|
526
689
|
});
|
|
527
690
|
}
|
|
528
691
|
const finalHeadText = stdoutText(finalHeadCommand, "recheck_head");
|
|
@@ -547,7 +710,8 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
547
710
|
commitId: inspectedCommitIds[0] ?? null,
|
|
548
711
|
});
|
|
549
712
|
}
|
|
550
|
-
if (
|
|
713
|
+
if (requestedProvenanceMode === "automatic" &&
|
|
714
|
+
/(?:^|\n)R\d+\t/.test(renameText)) {
|
|
551
715
|
incompleteCauses.push({
|
|
552
716
|
cause: "unsupported_rename",
|
|
553
717
|
commitId: null,
|
|
@@ -578,6 +742,7 @@ export async function probeGitHistory(request, dependencies = {}) {
|
|
|
578
742
|
inspectedCommitIds: Object.freeze(inspectedCommitIds),
|
|
579
743
|
snapshots: Object.freeze(snapshots),
|
|
580
744
|
availability: allCauses,
|
|
745
|
+
provenance,
|
|
581
746
|
};
|
|
582
747
|
}
|
|
583
748
|
function historicalLimits(overrides) {
|