@ricsam/r5d-worker 0.0.100 → 0.0.101
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/cjs/package.json +1 -1
- package/dist/cjs/working-tree-mirror.cjs +347 -99
- package/dist/cjs/workspace-git-sync.cjs +144 -22
- package/dist/cjs/workspace-merge-projection.cjs +5 -19
- package/dist/mjs/package.json +1 -1
- package/dist/mjs/working-tree-mirror.mjs +347 -99
- package/dist/mjs/workspace-git-sync.mjs +144 -22
- package/dist/mjs/workspace-merge-projection.mjs +5 -19
- package/dist/types/working-tree-mirror.d.ts +56 -11
- package/dist/types/workspace-git-sync.d.ts +17 -2
- package/package.json +1 -1
|
@@ -128,6 +128,22 @@ async function gitAsync(cwd, args, action) {
|
|
|
128
128
|
if (result.exitCode !== 0) throw new Error(`${action}: ${result.stderr || result.stdout || `git exited ${result.exitCode}`}`);
|
|
129
129
|
return result.stdout;
|
|
130
130
|
}
|
|
131
|
+
async function gitOutputAsync(cwd, args, action, input) {
|
|
132
|
+
const subprocess = Bun.spawn(gitCommandArgs(args), {
|
|
133
|
+
cwd,
|
|
134
|
+
stdin: input ?? "ignore",
|
|
135
|
+
stdout: "pipe",
|
|
136
|
+
stderr: "pipe",
|
|
137
|
+
env: (0, import_git_process_environment.workerGitProcessEnvironment)()
|
|
138
|
+
});
|
|
139
|
+
const [stdout, stderr, exitCode] = await Promise.all([
|
|
140
|
+
new Response(subprocess.stdout).arrayBuffer(),
|
|
141
|
+
new Response(subprocess.stderr).text(),
|
|
142
|
+
subprocess.exited
|
|
143
|
+
]);
|
|
144
|
+
if (exitCode !== 0) throw new Error(`${action}: ${stderr.trim() || `git exited ${exitCode}`}`);
|
|
145
|
+
return Buffer.from(stdout);
|
|
146
|
+
}
|
|
131
147
|
async function tryGitAsync(cwd, args) {
|
|
132
148
|
return (await gitResultAsync(cwd, args)).exitCode === 0;
|
|
133
149
|
}
|
|
@@ -1139,7 +1155,13 @@ function beginHydrationTransaction(workspacePath, mounts, targetReceipt) {
|
|
|
1139
1155
|
candidate: outerPath,
|
|
1140
1156
|
label: `Workspace mount ${mount.id} outer source`
|
|
1141
1157
|
});
|
|
1142
|
-
const plan = (0, import_working_tree_mirror.planWorkingTreeMirror)({
|
|
1158
|
+
const plan = (0, import_working_tree_mirror.planWorkingTreeMirror)({
|
|
1159
|
+
sourceRoot: outerPath,
|
|
1160
|
+
targetRoot: sourcePath,
|
|
1161
|
+
sourceMode: "all",
|
|
1162
|
+
deletionMode: "git",
|
|
1163
|
+
sourceGitlinks: outerSubtreeGitlinks(workspacePath, mount)
|
|
1164
|
+
});
|
|
1143
1165
|
scope = (0, import_working_tree_mirror.captureWorkingTreeMirrorPlan)({
|
|
1144
1166
|
plan,
|
|
1145
1167
|
targetRoot: sourcePath,
|
|
@@ -1450,6 +1472,7 @@ function activeMounts(mounts) {
|
|
|
1450
1472
|
return { active, tombstones, skipped };
|
|
1451
1473
|
}
|
|
1452
1474
|
function mirrorMountsToWorkspace(workspacePath, mounts) {
|
|
1475
|
+
const projected = [];
|
|
1453
1476
|
for (const mount of mounts) {
|
|
1454
1477
|
(0, import_workspace_mount_boundary.assertManagedDirectoryPath)({
|
|
1455
1478
|
trustedRoot: mount.durabilityRootPath,
|
|
@@ -1461,13 +1484,61 @@ function mirrorMountsToWorkspace(workspacePath, mounts) {
|
|
|
1461
1484
|
candidate: import_node_path.default.join(workspacePath, ...mount.workspaceRelativePath.replace(/\\/g, "/").split("/")),
|
|
1462
1485
|
label: `Workspace mount ${mount.id} outer target`
|
|
1463
1486
|
});
|
|
1464
|
-
(0, import_working_tree_mirror.mirrorWorkingTree)({
|
|
1487
|
+
const mirrored = (0, import_working_tree_mirror.mirrorWorkingTree)({
|
|
1465
1488
|
sourceRoot: mount.sourcePath,
|
|
1466
1489
|
targetRoot: import_node_path.default.join(workspacePath, ...mount.workspaceRelativePath.replace(/\\/g, "/").split("/")),
|
|
1467
1490
|
sourceMode: mount.sourceMode,
|
|
1468
1491
|
deletionMode: "all"
|
|
1469
1492
|
});
|
|
1493
|
+
projected.push({ mount, gitlinks: mirrored.gitlinks });
|
|
1494
|
+
}
|
|
1495
|
+
return projected;
|
|
1496
|
+
}
|
|
1497
|
+
async function stageWorkspaceGitlinks(workspacePath, projected) {
|
|
1498
|
+
if (projected.length === 0) return;
|
|
1499
|
+
const mountPaths = projected.map(({ mount }) => normalizedWorkspaceMountPath(mount.workspaceRelativePath));
|
|
1500
|
+
const desired = /* @__PURE__ */ new Map();
|
|
1501
|
+
projected.forEach(({ gitlinks }, index) => {
|
|
1502
|
+
for (const gitlink of gitlinks) desired.set(`${mountPaths[index]}/${gitlink.relativePath}`, gitlink.objectId);
|
|
1503
|
+
});
|
|
1504
|
+
const desiredRoots = new Set(desired.keys());
|
|
1505
|
+
const listed = await gitOutputAsync(
|
|
1506
|
+
workspacePath,
|
|
1507
|
+
["ls-files", "-z", "--stage", "--", ...mountPaths.map((mountPath) => `:(literal)${mountPath}`)],
|
|
1508
|
+
"inspect staged workspace mount entries"
|
|
1509
|
+
);
|
|
1510
|
+
const feed = [];
|
|
1511
|
+
const current = /* @__PURE__ */ new Map();
|
|
1512
|
+
const drop = (objectId, relativePath) => {
|
|
1513
|
+
feed.push(Buffer.concat([Buffer.from(`0 ${"0".repeat(objectId.length)} `), Buffer.from(relativePath), Buffer.from([0])]));
|
|
1514
|
+
};
|
|
1515
|
+
for (const record of listed.toString().split("\0")) {
|
|
1516
|
+
const match = /^([0-7]{6}) ([0-9a-f]{40,64}) [0-3]\t(.+)$/su.exec(record);
|
|
1517
|
+
if (!match) continue;
|
|
1518
|
+
const mode = match[1];
|
|
1519
|
+
const objectId = match[2];
|
|
1520
|
+
const relativePath = match[3];
|
|
1521
|
+
if (mode === "160000") {
|
|
1522
|
+
current.set(relativePath, objectId);
|
|
1523
|
+
if (!desired.has(relativePath)) drop(objectId, relativePath);
|
|
1524
|
+
continue;
|
|
1525
|
+
}
|
|
1526
|
+
if (desired.has(relativePath) || hasAncestorIn(relativePath, desiredRoots)) drop(objectId, relativePath);
|
|
1470
1527
|
}
|
|
1528
|
+
for (const [relativePath, objectId] of desired) {
|
|
1529
|
+
if (current.get(relativePath) === objectId) continue;
|
|
1530
|
+
feed.push(Buffer.concat([Buffer.from(`160000 ${objectId} `), Buffer.from(relativePath), Buffer.from([0])]));
|
|
1531
|
+
}
|
|
1532
|
+
if (feed.length === 0) return;
|
|
1533
|
+
await gitOutputAsync(workspacePath, ["update-index", "-z", "--index-info"], "stage workspace gitlinks", Buffer.concat(feed));
|
|
1534
|
+
}
|
|
1535
|
+
function hasAncestorIn(relativePath, ancestors) {
|
|
1536
|
+
let parent = import_node_path.default.posix.dirname(relativePath);
|
|
1537
|
+
while (parent !== ".") {
|
|
1538
|
+
if (ancestors.has(parent)) return true;
|
|
1539
|
+
parent = import_node_path.default.posix.dirname(parent);
|
|
1540
|
+
}
|
|
1541
|
+
return false;
|
|
1471
1542
|
}
|
|
1472
1543
|
function removeWorkspaceMounts(workspacePath, mounts) {
|
|
1473
1544
|
for (const mount of mounts) {
|
|
@@ -1507,6 +1578,24 @@ function restoreDeferredWorkspaceMountsFromHead(workspacePath, mounts) {
|
|
|
1507
1578
|
function workspaceMountOuterPath(workspacePath, mount) {
|
|
1508
1579
|
return import_node_path.default.join(workspacePath, ...mount.workspaceRelativePath.replace(/\\/g, "/").split("/"));
|
|
1509
1580
|
}
|
|
1581
|
+
function outerSubtreeGitlinks(workspacePath, mount) {
|
|
1582
|
+
const gitlinks = /* @__PURE__ */ new Map();
|
|
1583
|
+
const head = revParse(workspacePath, "HEAD");
|
|
1584
|
+
if (!head) return gitlinks;
|
|
1585
|
+
const subtree = `${head}:${normalizedWorkspaceMountPath(mount.workspaceRelativePath)}`;
|
|
1586
|
+
const listed = Bun.spawnSync(gitCommandArgs(["ls-tree", "-r", "-z", subtree]), {
|
|
1587
|
+
cwd: workspacePath,
|
|
1588
|
+
stdout: "pipe",
|
|
1589
|
+
stderr: "pipe",
|
|
1590
|
+
env: (0, import_git_process_environment.workerGitProcessEnvironment)()
|
|
1591
|
+
});
|
|
1592
|
+
if (listed.exitCode !== 0) return gitlinks;
|
|
1593
|
+
for (const record of Buffer.from(listed.stdout).toString().split("\0")) {
|
|
1594
|
+
const match = /^160000 commit ([0-9a-f]{40,64})\t(.+)$/su.exec(record);
|
|
1595
|
+
if (match) gitlinks.set(match[2], match[1]);
|
|
1596
|
+
}
|
|
1597
|
+
return gitlinks;
|
|
1598
|
+
}
|
|
1510
1599
|
function hydrateWorkspaceGitMountsRaw(workspacePath, mounts, options = {}) {
|
|
1511
1600
|
const hydratedMountIds = [];
|
|
1512
1601
|
const skippedMountIds = [];
|
|
@@ -1550,6 +1639,9 @@ function hydrateWorkspaceGitMountsRaw(workspacePath, mounts, options = {}) {
|
|
|
1550
1639
|
sourceRoot,
|
|
1551
1640
|
targetRoot: mount.sourcePath,
|
|
1552
1641
|
sourceMode: "all",
|
|
1642
|
+
// The outer worktree shows a submodule as an empty directory; the tree
|
|
1643
|
+
// carries its pointer, which a Git checkout applies to its index (D4).
|
|
1644
|
+
sourceGitlinks: outerSubtreeGitlinks(workspacePath, mount),
|
|
1553
1645
|
// A missing checkout has no Git index to define git-only deletions. Its
|
|
1554
1646
|
// newly created directory is empty, so all-mode is equivalent and lets
|
|
1555
1647
|
// bootstrap hydration preserve the fetched tree before Git initializes.
|
|
@@ -1565,7 +1657,7 @@ async function selectMountsWithUnchangedOuterSubtree(workspacePath, receipt, hea
|
|
|
1565
1657
|
return basisHead && basisHead !== head ? [{ mount, basisHead }] : [];
|
|
1566
1658
|
});
|
|
1567
1659
|
if (candidates.length === 0) return /* @__PURE__ */ new Set();
|
|
1568
|
-
const objects = await
|
|
1660
|
+
const objects = await resolveGitObjectsAsync(
|
|
1569
1661
|
workspacePath,
|
|
1570
1662
|
candidates.flatMap(({ mount, basisHead }) => [
|
|
1571
1663
|
workspaceTreeObjectName(basisHead, mount.workspaceRelativePath),
|
|
@@ -1574,8 +1666,8 @@ async function selectMountsWithUnchangedOuterSubtree(workspacePath, receipt, hea
|
|
|
1574
1666
|
);
|
|
1575
1667
|
const unchanged = /* @__PURE__ */ new Set();
|
|
1576
1668
|
for (const { mount, basisHead } of candidates) {
|
|
1577
|
-
const before = objects.get(workspaceTreeObjectName(basisHead, mount.workspaceRelativePath)) ?? null;
|
|
1578
|
-
const after = objects.get(workspaceTreeObjectName(head, mount.workspaceRelativePath)) ?? null;
|
|
1669
|
+
const before = objects.get(workspaceTreeObjectName(basisHead, mount.workspaceRelativePath))?.objectId ?? null;
|
|
1670
|
+
const after = objects.get(workspaceTreeObjectName(head, mount.workspaceRelativePath))?.objectId ?? null;
|
|
1579
1671
|
if (before === after) unchanged.add(mount.id);
|
|
1580
1672
|
}
|
|
1581
1673
|
return unchanged;
|
|
@@ -1841,7 +1933,7 @@ async function diffSizeBytes(workspacePath, baseRevision, headRevision, limit, p
|
|
|
1841
1933
|
if (exitCode !== 0) throw new Error(`Measure workspace diff: ${stderr || `git exited ${exitCode}`}`);
|
|
1842
1934
|
return total;
|
|
1843
1935
|
}
|
|
1844
|
-
async function
|
|
1936
|
+
async function resolveGitObjectsAsync(workspacePath, names) {
|
|
1845
1937
|
const resolved = /* @__PURE__ */ new Map();
|
|
1846
1938
|
const unique = [...new Set(names)];
|
|
1847
1939
|
if (unique.length === 0) return resolved;
|
|
@@ -1864,21 +1956,43 @@ async function resolveGitObjectIdsAsync(workspacePath, names) {
|
|
|
1864
1956
|
throw new Error(`Resolve workspace objects: expected ${unique.length} results, received ${lines.length}`);
|
|
1865
1957
|
}
|
|
1866
1958
|
unique.forEach((name, index) => {
|
|
1867
|
-
const match = /^([0-9a-f]{40,64}) \S+ \d+$/.exec(lines[index]);
|
|
1868
|
-
resolved.set(name, match ? match[1] : null);
|
|
1959
|
+
const match = /^([0-9a-f]{40,64}) (\S+) \d+$/.exec(lines[index]);
|
|
1960
|
+
resolved.set(name, match ? { objectId: match[1], type: match[2] } : null);
|
|
1869
1961
|
});
|
|
1870
1962
|
return resolved;
|
|
1871
1963
|
}
|
|
1872
1964
|
function workspaceTreeObjectName(revision, workspaceRelativePath) {
|
|
1873
1965
|
return `${revision}:${normalizedWorkspaceMountPath(workspaceRelativePath)}`;
|
|
1874
1966
|
}
|
|
1967
|
+
async function pathsReplacedByGitlinks(workspacePath, baseRevision, headRevision) {
|
|
1968
|
+
const base = baseRevision ?? emptyTreeHash(workspacePath);
|
|
1969
|
+
const raw = await gitOutputAsync(
|
|
1970
|
+
workspacePath,
|
|
1971
|
+
["diff", "--raw", "--no-renames", "-z", base, headRevision],
|
|
1972
|
+
"inspect workspace gitlink changes"
|
|
1973
|
+
);
|
|
1974
|
+
const records = raw.toString().split("\0");
|
|
1975
|
+
const addedGitlinks = [];
|
|
1976
|
+
for (let index = 0; index + 1 < records.length; index += 2) {
|
|
1977
|
+
if (/^:[0-7]{6} 160000 \S+ \S+ A$/u.test(records[index])) addedGitlinks.push(records[index + 1]);
|
|
1978
|
+
}
|
|
1979
|
+
if (addedGitlinks.length === 0) return [];
|
|
1980
|
+
const objects = await resolveGitObjectsAsync(
|
|
1981
|
+
workspacePath,
|
|
1982
|
+
addedGitlinks.map((relativePath) => `${base}:${relativePath}`)
|
|
1983
|
+
);
|
|
1984
|
+
return addedGitlinks.filter((relativePath) => objects.get(`${base}:${relativePath}`)?.type === "tree").sort();
|
|
1985
|
+
}
|
|
1986
|
+
function gitlinkMigrationPathspecs(paths) {
|
|
1987
|
+
return paths.map((relativePath) => `:(exclude,literal)${relativePath}`);
|
|
1988
|
+
}
|
|
1875
1989
|
async function measureInitialPublicationDiffSize(input) {
|
|
1876
1990
|
const candidates = input.mounts.filter(
|
|
1877
1991
|
(mount) => typeof mount.initialPublicationSourceRelativePath === "string"
|
|
1878
1992
|
);
|
|
1879
1993
|
if (candidates.length === 0) return null;
|
|
1880
1994
|
const revisions = [input.localHead, ...input.remoteHead ? [input.remoteHead] : []];
|
|
1881
|
-
const objects = await
|
|
1995
|
+
const objects = await resolveGitObjectsAsync(
|
|
1882
1996
|
input.workspacePath,
|
|
1883
1997
|
candidates.flatMap(
|
|
1884
1998
|
(mount) => revisions.flatMap((revision) => [
|
|
@@ -1887,7 +2001,7 @@ async function measureInitialPublicationDiffSize(input) {
|
|
|
1887
2001
|
])
|
|
1888
2002
|
)
|
|
1889
2003
|
);
|
|
1890
|
-
const lookup = (revision, workspaceRelativePath) => revision ? objects.get(workspaceTreeObjectName(revision, workspaceRelativePath)) ?? null : null;
|
|
2004
|
+
const lookup = (revision, workspaceRelativePath) => revision ? objects.get(workspaceTreeObjectName(revision, workspaceRelativePath))?.objectId ?? null : null;
|
|
1891
2005
|
const initialPublications = candidates.flatMap((mount) => {
|
|
1892
2006
|
const published = lookup(input.localHead, mount.workspaceRelativePath);
|
|
1893
2007
|
if (!published || lookup(input.remoteHead, mount.workspaceRelativePath)) return [];
|
|
@@ -1895,16 +2009,14 @@ async function measureInitialPublicationDiffSize(input) {
|
|
|
1895
2009
|
return [{ mount, published, source }];
|
|
1896
2010
|
});
|
|
1897
2011
|
if (initialPublications.length === 0) return null;
|
|
1898
|
-
let size = await input.measure(
|
|
1899
|
-
|
|
1900
|
-
input.
|
|
1901
|
-
|
|
1902
|
-
input.limit,
|
|
1903
|
-
initialPublications.map(({ mount }) => `:(exclude,literal)${normalizedWorkspaceMountPath(mount.workspaceRelativePath)}`)
|
|
1904
|
-
);
|
|
2012
|
+
let size = await input.measure(input.workspacePath, input.remoteHead, input.localHead, input.limit, [
|
|
2013
|
+
...initialPublications.map(({ mount }) => `:(exclude,literal)${normalizedWorkspaceMountPath(mount.workspaceRelativePath)}`),
|
|
2014
|
+
...input.excludePathspecs ?? []
|
|
2015
|
+
]);
|
|
1905
2016
|
for (const { published, source } of initialPublications) {
|
|
1906
2017
|
if (size > input.limit) break;
|
|
1907
|
-
|
|
2018
|
+
const migrations = source ? await pathsReplacedByGitlinks(input.workspacePath, source, published) : [];
|
|
2019
|
+
size += await input.measure(input.workspacePath, source, published, input.limit - size, gitlinkMigrationPathspecs(migrations));
|
|
1908
2020
|
}
|
|
1909
2021
|
return { size, mountIds: initialPublications.map(({ mount }) => mount.id).sort() };
|
|
1910
2022
|
}
|
|
@@ -2168,10 +2280,12 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
2168
2280
|
return classifyMounts([...selected.active, ...selected.tombstones], hydration.skippedMountIds);
|
|
2169
2281
|
};
|
|
2170
2282
|
let newlyStagedPaths = [];
|
|
2283
|
+
const projectedGitlinks = [];
|
|
2171
2284
|
const stageAndCommitWorkspace = async () => {
|
|
2172
2285
|
if (workspaceResolutionInProgress(workspacePath) || await workspaceHasUnmergedEntries(workspacePath)) {
|
|
2173
2286
|
throw new Error("Outer workspace clone has an unfinished merge/rebase; finish or abort it before synchronizing");
|
|
2174
2287
|
}
|
|
2288
|
+
await stageWorkspaceGitlinks(workspacePath, projectedGitlinks);
|
|
2175
2289
|
await gitAsync(workspacePath, ["add", "-A", "--", "."], "stage workspace working trees");
|
|
2176
2290
|
newlyStagedPaths = await stagedPaths(workspacePath);
|
|
2177
2291
|
if (newlyStagedPaths.length > 0) {
|
|
@@ -2201,7 +2315,7 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
2201
2315
|
cycleSkippedMountIds.add(mount.id);
|
|
2202
2316
|
continue;
|
|
2203
2317
|
}
|
|
2204
|
-
mirrorMountsToWorkspace(workspacePath, [mount]);
|
|
2318
|
+
projectedGitlinks.push(...mirrorMountsToWorkspace(workspacePath, [mount]));
|
|
2205
2319
|
projectedFastMounts.push(mount);
|
|
2206
2320
|
await yieldToWorkerEventLoop();
|
|
2207
2321
|
}
|
|
@@ -2300,7 +2414,9 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
2300
2414
|
}
|
|
2301
2415
|
const paths = await changedPaths(workspacePath, remoteHead, localHead);
|
|
2302
2416
|
const measureDiffSize = input.measureDiffSize ?? diffSizeBytes;
|
|
2303
|
-
|
|
2417
|
+
const gitlinkMigrations = paths.length > 0 ? await pathsReplacedByGitlinks(workspacePath, remoteHead, localHead) : [];
|
|
2418
|
+
const gitlinkMigrationExcludes = gitlinkMigrationPathspecs(gitlinkMigrations);
|
|
2419
|
+
let size = paths.length > 0 ? await measureDiffSize(workspacePath, remoteHead, localHead, maxDiffBytes, gitlinkMigrationExcludes) : 0;
|
|
2304
2420
|
input.assertStillAdmitted?.();
|
|
2305
2421
|
let initialPublicationMountIds;
|
|
2306
2422
|
if (paths.length > 0 && size > maxDiffBytes && !input.allowLargeDiff) {
|
|
@@ -2310,7 +2426,8 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
2310
2426
|
localHead,
|
|
2311
2427
|
mounts: input.mounts,
|
|
2312
2428
|
limit: maxDiffBytes,
|
|
2313
|
-
measure: measureDiffSize
|
|
2429
|
+
measure: measureDiffSize,
|
|
2430
|
+
excludePathspecs: gitlinkMigrationExcludes
|
|
2314
2431
|
});
|
|
2315
2432
|
input.assertStillAdmitted?.();
|
|
2316
2433
|
if (initialPublication && initialPublication.size <= maxDiffBytes) {
|
|
@@ -2318,6 +2435,11 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
2318
2435
|
initialPublicationMountIds = initialPublication.mountIds;
|
|
2319
2436
|
}
|
|
2320
2437
|
}
|
|
2438
|
+
let gitlinkMigrationConfirmed = false;
|
|
2439
|
+
if (gitlinkMigrations.length > 0 && size <= maxDiffBytes && !input.allowLargeDiff) {
|
|
2440
|
+
gitlinkMigrationConfirmed = await measureDiffSize(workspacePath, remoteHead, localHead, maxDiffBytes) > maxDiffBytes;
|
|
2441
|
+
input.assertStillAdmitted?.();
|
|
2442
|
+
}
|
|
2321
2443
|
if (paths.length > 0 && size > maxDiffBytes && !input.allowLargeDiff) {
|
|
2322
2444
|
const classifiedMounts = classifyMounts([...selected.active, ...selected.tombstones]);
|
|
2323
2445
|
return {
|
|
@@ -2362,7 +2484,7 @@ async function synchronizeWorkspaceGit(input) {
|
|
|
2362
2484
|
"push",
|
|
2363
2485
|
"--no-recurse-submodules"
|
|
2364
2486
|
];
|
|
2365
|
-
if (input.allowLargeDiff || initialPublicationMountIds) {
|
|
2487
|
+
if (input.allowLargeDiff || initialPublicationMountIds || gitlinkMigrationConfirmed) {
|
|
2366
2488
|
pushArgs.push(`--push-option=${WORKSPACE_GIT_CONFIRMED_LARGE_DIFF_PUSH_OPTION}`);
|
|
2367
2489
|
}
|
|
2368
2490
|
pushArgs.push("origin", `HEAD:refs/heads/${WORKSPACE_GIT_BRANCH}`);
|
|
@@ -206,14 +206,6 @@ function indexMode(entry) {
|
|
|
206
206
|
function indexInfoRecord(mode, objectId, relativePath) {
|
|
207
207
|
return Buffer.concat([Buffer.from(`${mode} ${objectId} `), Buffer.from(relativePath), Buffer.from([0])]);
|
|
208
208
|
}
|
|
209
|
-
function basisGitlinks(workspacePath, basis) {
|
|
210
|
-
const listed = gitResult(workspacePath, ["ls-tree", "-r", "-z", `${basis.basisHead}:${basis.workspaceRelativePath}`]);
|
|
211
|
-
if (listed.exitCode !== 0) return [];
|
|
212
|
-
return nulRecords(listed.stdout).flatMap((record) => {
|
|
213
|
-
const match = /^160000 commit ([0-9a-f]{40,64})\t(.+)$/su.exec(record.toString());
|
|
214
|
-
return match ? [{ objectId: match[1], relativePath: match[2] }] : [];
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
209
|
function synthesizeMountTree(input) {
|
|
218
210
|
const sourceRoot = import_node_path.default.resolve(input.sourcePath);
|
|
219
211
|
const entries = (0, import_working_tree_mirror.inspectWorkingTree)(sourceRoot, input.sourceMode);
|
|
@@ -224,19 +216,14 @@ function synthesizeMountTree(input) {
|
|
|
224
216
|
const records = [];
|
|
225
217
|
for (const [relativePath, entry] of [...entries.entries()].sort(([left], [right]) => left.localeCompare(right))) {
|
|
226
218
|
if (entry.kind === "directory") continue;
|
|
219
|
+
if (entry.kind === "gitlink") {
|
|
220
|
+
records.push(indexInfoRecord("160000", entry.objectId, relativePath));
|
|
221
|
+
continue;
|
|
222
|
+
}
|
|
227
223
|
const sourcePath = sourceEntryPath(sourceRoot, relativePath);
|
|
228
224
|
const objectId = entry.kind === "file" ? hashRegularFile(input.workspacePath, sourcePath, entry) : hashSymlink(input.workspacePath, sourcePath, entry);
|
|
229
225
|
records.push(indexInfoRecord(indexMode(entry), objectId, relativePath));
|
|
230
226
|
}
|
|
231
|
-
if (input.gitlinkBasis && input.sourceMode === "git") {
|
|
232
|
-
for (const gitlink of basisGitlinks(input.workspacePath, input.gitlinkBasis)) {
|
|
233
|
-
const populatedPrefix = `${gitlink.relativePath}/`;
|
|
234
|
-
const populated = [...entries.keys()].some((relativePath) => relativePath.startsWith(populatedPrefix));
|
|
235
|
-
if (entries.get(gitlink.relativePath)?.kind === "directory" && !populated) {
|
|
236
|
-
records.push(indexInfoRecord("160000", gitlink.objectId, gitlink.relativePath));
|
|
237
|
-
}
|
|
238
|
-
}
|
|
239
|
-
}
|
|
240
227
|
if (records.length > 0) {
|
|
241
228
|
git(input.workspacePath, ["update-index", "-z", "--index-info"], "populate workspace projection index", {
|
|
242
229
|
environment,
|
|
@@ -301,8 +288,7 @@ function synthesizeOursCommit(input) {
|
|
|
301
288
|
const mountTree = synthesizeMountTree({
|
|
302
289
|
workspacePath: input.workspacePath,
|
|
303
290
|
sourcePath: input.mount.sourcePath,
|
|
304
|
-
sourceMode: input.mount.sourceMode
|
|
305
|
-
gitlinkBasis: { basisHead: input.basisHead, workspaceRelativePath: input.workspaceRelativePath }
|
|
291
|
+
sourceMode: input.mount.sourceMode
|
|
306
292
|
});
|
|
307
293
|
const rootTree = graftMountTree({
|
|
308
294
|
workspacePath: input.workspacePath,
|
package/dist/mjs/package.json
CHANGED