gitnexus 1.6.13-rc.46 → 1.6.13-rc.47
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/core/run-analyze.js
CHANGED
|
@@ -1605,6 +1605,36 @@ async function runFullAnalysisInner(repoPath, options, callbacks, writeTarget, c
|
|
|
1605
1605
|
// fast path because the previous analyze just wrote them
|
|
1606
1606
|
// (regression vs PR #1233 behavior).
|
|
1607
1607
|
const dirty = isWorkingTreeDirty(repoPath);
|
|
1608
|
+
// A clean porcelain status is not enough when the previous index captured
|
|
1609
|
+
// uncommitted content at this same HEAD: assume-unchanged and skip-worktree
|
|
1610
|
+
// paths are deliberately absent from porcelain. Re-hash only the paths
|
|
1611
|
+
// recorded dirty by the previous run. Matching hashes mean the index still
|
|
1612
|
+
// describes disk and may take the fast path; a mismatch (including an
|
|
1613
|
+
// unreadable/deleted file) must fall through to incremental reconciliation.
|
|
1614
|
+
const indexedDirtyPaths = existingMeta.indexCoverage?.dirtyPaths ?? [];
|
|
1615
|
+
let indexedContentChanged = indexedDirtyPaths.length > 0;
|
|
1616
|
+
let reconciledCleanCoverage = false;
|
|
1617
|
+
if (!dirty && existingMeta.fileHashes) {
|
|
1618
|
+
// Porcelain also hides newly edited assume-unchanged/skip-worktree
|
|
1619
|
+
// paths that were absent from the previous receipt. Include the live
|
|
1620
|
+
// hidden-path set in the bounded comparison so those edits cannot take
|
|
1621
|
+
// the fast path and publish stale content for HEAD.
|
|
1622
|
+
const liveDirtyPaths = listWorkingTreeDirtyPaths(repoPath);
|
|
1623
|
+
if (liveDirtyPaths === null) {
|
|
1624
|
+
indexedContentChanged = true;
|
|
1625
|
+
}
|
|
1626
|
+
else {
|
|
1627
|
+
const pathsToCheck = [...new Set([...indexedDirtyPaths, ...liveDirtyPaths])].filter((rel) => existingMeta.fileHashes?.[rel] !== undefined);
|
|
1628
|
+
const currentDirtyHashes = await computeFileHashes(repoPath, pathsToCheck);
|
|
1629
|
+
indexedContentChanged = pathsToCheck.some((rel) => currentDirtyHashes.get(rel) !== existingMeta.fileHashes?.[rel]);
|
|
1630
|
+
// A mode-only dirty snapshot can leave a coverage receipt even though
|
|
1631
|
+
// restoring the mode makes porcelain clean and content hashes equal.
|
|
1632
|
+
// Clear that receipt before taking the fast path; otherwise shared
|
|
1633
|
+
// publication remains blocked forever despite a clean checkout.
|
|
1634
|
+
reconciledCleanCoverage =
|
|
1635
|
+
!indexedContentChanged && indexedDirtyPaths.length > 0 && liveDirtyPaths.length === 0;
|
|
1636
|
+
}
|
|
1637
|
+
}
|
|
1608
1638
|
// Registration wrinkle around the fast path (#2264). A prior
|
|
1609
1639
|
// `analyze --name X` that hit a name collision writes meta.json (meta-save
|
|
1610
1640
|
// runs before registerRepo) then fails before registering, leaving the
|
|
@@ -1618,6 +1648,20 @@ async function runFullAnalysisInner(repoPath, options, callbacks, writeTarget, c
|
|
|
1618
1648
|
// possibly half-finalized index. `isRepoRegistered` is only read on the
|
|
1619
1649
|
// opt-in branch so the common fast path keeps its single-stat cost.
|
|
1620
1650
|
const healUnregistered = options.allowDuplicateName === true && !(await isRepoRegistered(repoPath));
|
|
1651
|
+
if (reconciledCleanCoverage) {
|
|
1652
|
+
try {
|
|
1653
|
+
existingMeta.indexCoverage = {
|
|
1654
|
+
...existingMeta.indexCoverage,
|
|
1655
|
+
dirtyPaths: [],
|
|
1656
|
+
};
|
|
1657
|
+
await saveMeta(metaDir, existingMeta);
|
|
1658
|
+
}
|
|
1659
|
+
catch {
|
|
1660
|
+
// If the receipt cannot be persisted, fall through to the normal
|
|
1661
|
+
// reconciliation path instead of returning with stale metadata.
|
|
1662
|
+
indexedContentChanged = true;
|
|
1663
|
+
}
|
|
1664
|
+
}
|
|
1621
1665
|
// §5.C is deliberately NOT self-healed here. An #2841 FTS-forced rebuild
|
|
1622
1666
|
// stamps `lastCommit`, so a plain rerun lands on this fast path and the
|
|
1623
1667
|
// search indexes stay missing until the next content change. The fix for
|
|
@@ -1633,7 +1677,7 @@ async function runFullAnalysisInner(repoPath, options, callbacks, writeTarget, c
|
|
|
1633
1677
|
// re-analysis whenever an index authored where FTS was unavailable was
|
|
1634
1678
|
// later read on a host where it loads — which is a legitimate, common
|
|
1635
1679
|
// state, and the invariant `analyzer-identity-cli.test.ts` pins.
|
|
1636
|
-
if (!dirty && !healUnregistered) {
|
|
1680
|
+
if (!dirty && !indexedContentChanged && !healUnregistered) {
|
|
1637
1681
|
const processDetectionStamp = existingMeta.processDetection ?? toProcessDetectionStamp(processDetectionBudget);
|
|
1638
1682
|
if (options.registryName) {
|
|
1639
1683
|
await registerRepo(repoPath, existingMeta, {
|
|
@@ -321,9 +321,8 @@ export const publishSharedGraph = async (layout, repoPath, currentCommit, log) =
|
|
|
321
321
|
if (!meta)
|
|
322
322
|
return;
|
|
323
323
|
const own = path.join(slot, LBUG_DIRECTORY);
|
|
324
|
-
// A graph built while files were dirty
|
|
325
|
-
//
|
|
326
|
-
// only a graph whose build saw no dirty covered file may become shared.
|
|
324
|
+
// A graph built while files were dirty must not become shared until analyze
|
|
325
|
+
// has reconciled those paths with disk and cleared them from the coverage receipt.
|
|
327
326
|
const builtClean = (meta.indexCoverage?.dirtyPaths ?? []).length === 0;
|
|
328
327
|
const shareable = currentCommit !== '' &&
|
|
329
328
|
meta.lastCommit === currentCommit &&
|
package/package.json
CHANGED