stim 1.3.1 → 1.5.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/README.md +16 -3
- package/dist/{android-hMj83VpN.mjs → android-DJWiTBkz.mjs} +65 -72
- package/dist/{android-cas-DXorPCi_.mjs → android-cas-CSS8gjR7.mjs} +15 -12
- package/dist/{android-CT-PkXUh.mjs → android-sobvO9ia.mjs} +197 -114
- package/dist/{app-install-DIp9riNx.mjs → app-install--PAocWvq.mjs} +2 -2
- package/dist/{build-slots-C4AouyNz.mjs → build-slots-CuPszJDu.mjs} +7 -8
- package/dist/{cache-manifest-CXR-Y8pH.mjs → cache-manifest-uoOKhgUD.mjs} +1 -1
- package/dist/cache-manifest.mjs +1 -1
- package/dist/cli.mjs +14 -13
- package/dist/collector-run.mjs +4 -4
- package/dist/{command-output-8wHMEde0.mjs → command-output-BuIb_ZOI.mjs} +1 -4
- package/dist/{config-CcefMY2Q.mjs → config-DMP7L7H6.mjs} +52 -52
- package/dist/dependency-state-CTL8A9p3.mjs +76 -0
- package/dist/{deps-0Yt0Inly.mjs → deps-BAGOnrc7.mjs} +1 -1
- package/dist/{dev-client-VfSZNLT4.mjs → dev-client-BoifdqkU.mjs} +12 -12
- package/dist/{device-Bbv45Z9Z.mjs → device-BUw4JBuH.mjs} +7 -7
- package/dist/{xcode-xnxyvJkD.mjs → device-DvKJ454A.mjs} +208 -967
- package/dist/{device-lease-CJwK7OZr.mjs → device-lease-r7yEQ1R8.mjs} +3 -3
- package/dist/{device-pool-CcBNTvM7.mjs → device-pool-DU4FQKp5.mjs} +4 -4
- package/dist/{device-remote-DAA0Zm6Z.mjs → device-remote-BTUqbl0i.mjs} +7 -6
- package/dist/{doctor-B4EITgQB.mjs → doctor-Di_B26uh.mjs} +396 -117
- package/dist/{error-diagnostics-DwhNBFDU.mjs → error-diagnostics-CTePWAzW.mjs} +7 -6
- package/dist/{gc-BRu62v4o.mjs → gc-C20dWw_8.mjs} +61 -27
- package/dist/{guide-D95E0u3i.mjs → guide-sAnoty2y.mjs} +151 -20
- package/dist/guide-status-BF6RsJJp.mjs +271 -0
- package/dist/{ios-DAju3TVy.mjs → ios-BdpkncL6.mjs} +2667 -2607
- package/dist/{ios-device-CWOM_S44.mjs → ios-device-DJOi9FR5.mjs} +1 -1
- package/dist/{logs-CAdwW6c2.mjs → logs-BfQdIhiF.mjs} +5 -5
- package/dist/metro-ato6ef3J.mjs +99 -0
- package/dist/named-ports-DH9SXd0f.mjs +137 -0
- package/dist/{ownership-8O073GIC.mjs → ownership-CD_XnpDu.mjs} +5 -5
- package/dist/{ownership-DXcol4oU.mjs → ownership-CVY9cqCr.mjs} +6 -6
- package/dist/ports-A6uTJSPj.mjs +39 -0
- package/dist/ports-BZprTJRa.mjs +90 -0
- package/dist/{project-fKmuIaMI.mjs → project-B_SDt4ip.mjs} +2 -2
- package/dist/{reclaim-CUmwucWG.mjs → reclaim-C_rB25f4.mjs} +20 -13
- package/dist/{reload-CWpXoOgN.mjs → reload-CYBJbJfI.mjs} +8 -8
- package/dist/rolldown-runtime-BsOwBuO_.mjs +30 -0
- package/dist/{server-bare-DEzPZLvf.mjs → server-bare-H3pAhbMs.mjs} +11 -35
- package/dist/server-expo-CSwUVYOa.mjs +2 -0
- package/dist/{server-expo-DizT4OMk.mjs → server-expo-Ds8_mfng.mjs} +6 -14
- package/dist/{settings-DEJf6_kJ.mjs → settings-kO2ZqIKy.mjs} +2 -2
- package/dist/{slot-launch-CZklomj6.mjs → slot-launch-BpHiHH6A.mjs} +4 -4
- package/dist/{start-B5G4NjiA.mjs → start-DiEfqEWk.mjs} +20 -22
- package/dist/state-CnWzvCWP.mjs +131 -0
- package/dist/{stats-CaaQr4yN.mjs → stats-DHrO0frH.mjs} +4 -4
- package/dist/{stats-BR-kwj0B.mjs → stats-Fo9ACIv7.mjs} +1 -1
- package/dist/{status-CI9clRSb.mjs → status-J5LAXpag.mjs} +15 -12
- package/dist/{stop-CjlgDk0a.mjs → stop-0jJNahwN.mjs} +15 -14
- package/dist/{stop-CQhffpmX.mjs → stop-CM1fejKW.mjs} +2 -2
- package/dist/supervisor-run.d.mts +7 -28
- package/dist/supervisor-run.mjs +20 -11
- package/dist/{teardown--gESs9ck.mjs → teardown-CAVcWeRD.mjs} +148 -109
- package/dist/{workspace-process-lock-IBj1Towr.mjs → workspace-process-lock-Bz19_R9R.mjs} +4 -4
- package/dist/workspace-state-WVwWw_hB.mjs +146 -0
- package/dist/{worktree-DtQGO9-s.mjs → worktree-CeUKDAQw.mjs} +38 -34
- package/dist/{worktree-Eq6TLH8N.mjs → worktree-DJnBbQZ9.mjs} +79 -22
- package/dist/xcode-BqDeRkpT.mjs +860 -0
- package/package.json +7 -7
- package/shim/expo-metro-config.cjs +11 -17
- package/dist/doctor-BueDfLYG.mjs +0 -530
- package/dist/metro-CORqXyTL.mjs +0 -184
- package/dist/ownership-claim-BtPtJVmq.mjs +0 -584
- package/dist/server-expo-44em5Pmg.mjs +0 -2
- package/dist/state-B3XA2wp2.mjs +0 -268
- package/shim/metro-cache-generation.cjs +0 -20
- package/shim/metro-cache-generation.d.cts +0 -5
|
@@ -1,17 +1,16 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { S as upsertProject, f as getProject, g as loadConfig, h as isPathPrefix, u as getConfigDir, v as removeProject, w as
|
|
3
|
-
import { c as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { a as formatElapsed, f as releasedLeaseFact, i as formatDuration, l as phaseLine, m as shortUdid, u as plural } from "./command-output-
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
import { n as
|
|
14
|
-
import { a as runPodInstall, i as runCaptured, n as podsAreStale, r as readPodState, t as DEPS_ERROR } from "./deps-0Yt0Inly.mjs";
|
|
2
|
+
import { E as ownership_claim_exports, S as upsertProject, f as getProject, g as loadConfig, h as isPathPrefix, u as getConfigDir, v as removeProject, w as process_identity_exports } from "./config-DMP7L7H6.mjs";
|
|
3
|
+
import { S as warmWorktreePaths, _ as resolveFullRef, b as sourceCheckoutOf, c as hasRemote, d as listWorktrees, f as locallyKnownUpstream, h as removeWorktree, i as depsOutOfSync, l as hasUncommittedWork, m as readWorktreeExclude, n as cloneIgnoredEntries, o as dirtyPaths, p as podsOutOfSync, r as deleteBranch, s as gitCommonDir, t as branchExists, u as isPodInstallChurn, x as unpushedCommits, y as restoreFile } from "./worktree-DJnBbQZ9.mjs";
|
|
4
|
+
import { a as findProjectRoot } from "./project-B_SDt4ip.mjs";
|
|
5
|
+
import { l as readRemoteSession, s as readMetroTunnel } from "./state-CnWzvCWP.mjs";
|
|
6
|
+
import { a as formatElapsed, f as releasedLeaseFact, i as formatDuration, l as phaseLine, m as shortUdid, u as plural } from "./command-output-BuIb_ZOI.mjs";
|
|
7
|
+
import { A as resolveSettings, I as unknownSettingKeys, N as settingShapeErrors, a as SETTING_SHAPE_REMEDY } from "./settings-kO2ZqIKy.mjs";
|
|
8
|
+
import { a as POOL_SETTING_REMEDY, l as parkedMaxSetting } from "./teardown-CAVcWeRD.mjs";
|
|
9
|
+
import { h as podInstallCommand, n as HEARTBEAT_INTERVAL_MS } from "./xcode-BqDeRkpT.mjs";
|
|
10
|
+
import { n as hasInstalledDependencies, r as installedNpmTreeIsValid, t as dependencyState } from "./dependency-state-CTL8A9p3.mjs";
|
|
11
|
+
import { c as withManagedTunnelRemovalLock, o as withManagedRemoteWorktreeRemovalLock } from "./ownership-CVY9cqCr.mjs";
|
|
12
|
+
import { n as reclaimProject } from "./reclaim-C_rB25f4.mjs";
|
|
13
|
+
import { a as runPodInstall, i as runCaptured, n as podsAreStale, r as readPodState, t as DEPS_ERROR } from "./deps-BAGOnrc7.mjs";
|
|
15
14
|
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
16
15
|
import { createHash, randomUUID } from "node:crypto";
|
|
17
16
|
import { join, relative } from "node:path";
|
|
@@ -72,22 +71,22 @@ function installerClaim(claim, { now, progressMs, out }) {
|
|
|
72
71
|
const forget = () => {
|
|
73
72
|
groups = [];
|
|
74
73
|
try {
|
|
75
|
-
clearClaimChild(claim);
|
|
74
|
+
(0, ownership_claim_exports.clearClaimChild)(claim);
|
|
76
75
|
} catch {}
|
|
77
76
|
};
|
|
78
|
-
const alive = () => groups.find((pid) => processGroupAlive(pid)) ?? null;
|
|
77
|
+
const alive = () => groups.find((pid) => (0, ownership_claim_exports.processGroupAlive)(pid)) ?? null;
|
|
79
78
|
return {
|
|
80
|
-
declare: () => markClaimChildPending(claim),
|
|
79
|
+
declare: () => (0, ownership_claim_exports.markClaimChildPending)(claim),
|
|
81
80
|
record: (pid) => {
|
|
82
81
|
if (pid === null) {
|
|
83
82
|
forget();
|
|
84
83
|
return;
|
|
85
84
|
}
|
|
86
85
|
groups.push(pid);
|
|
87
|
-
const captured = captureProcessIdentity(pid);
|
|
86
|
+
const captured = (0, process_identity_exports.captureProcessIdentity)(pid);
|
|
88
87
|
let failure = captured.ok ? null : captured.reason;
|
|
89
88
|
if (captured.ok) try {
|
|
90
|
-
setClaimChild(claim, {
|
|
89
|
+
(0, ownership_claim_exports.setClaimChild)(claim, {
|
|
91
90
|
pid,
|
|
92
91
|
processToken: captured.token
|
|
93
92
|
});
|
|
@@ -95,7 +94,7 @@ function installerClaim(claim, { now, progressMs, out }) {
|
|
|
95
94
|
} catch (error) {
|
|
96
95
|
failure = error?.message ?? String(error);
|
|
97
96
|
}
|
|
98
|
-
if (!processGroupAlive(pid)) {
|
|
97
|
+
if (!(0, ownership_claim_exports.processGroupAlive)(pid)) {
|
|
99
98
|
forget();
|
|
100
99
|
return;
|
|
101
100
|
}
|
|
@@ -132,7 +131,7 @@ function installerClaim(claim, { now, progressMs, out }) {
|
|
|
132
131
|
}
|
|
133
132
|
function timeoutError(holder, elapsedMs, root) {
|
|
134
133
|
const who = holder ? `${warmCommand(holder.phase)} (pid ${holder.pid})` : "another stim worktree warm";
|
|
135
|
-
const error = /* @__PURE__ */ new Error(`Waited ${formatElapsed(elapsedMs)} for ${who} to release the warm lock on this repository. The lock is ${root}; remove it if nothing is really warming:\n ${claimRemoveCommand(root)}`);
|
|
134
|
+
const error = /* @__PURE__ */ new Error(`Waited ${formatElapsed(elapsedMs)} for ${who} to release the warm lock on this repository. The lock is ${root}; remove it if nothing is really warming:\n ${(0, ownership_claim_exports.claimRemoveCommand)(root)}`);
|
|
136
135
|
error.code = "STIM_LOCK_TIMEOUT";
|
|
137
136
|
return error;
|
|
138
137
|
}
|
|
@@ -144,7 +143,7 @@ async function acquireWarmClaim({ repositoryRoot, phase, mode = phase === "refre
|
|
|
144
143
|
let pending = null;
|
|
145
144
|
try {
|
|
146
145
|
for (;;) {
|
|
147
|
-
const attempt = pending ? settleClaim(pending) : tryAcquireClaim({
|
|
146
|
+
const attempt = pending ? (0, ownership_claim_exports.settleClaim)(pending) : (0, ownership_claim_exports.tryAcquireClaim)({
|
|
148
147
|
root,
|
|
149
148
|
mode,
|
|
150
149
|
label: WARM_CLAIM_LABEL
|
|
@@ -164,7 +163,7 @@ async function acquireWarmClaim({ repositoryRoot, phase, mode = phase === "refre
|
|
|
164
163
|
installer,
|
|
165
164
|
release: () => {
|
|
166
165
|
if (installer.holding()) return;
|
|
167
|
-
releaseClaim(acquired);
|
|
166
|
+
(0, ownership_claim_exports.releaseClaim)(acquired);
|
|
168
167
|
}
|
|
169
168
|
};
|
|
170
169
|
}
|
|
@@ -180,13 +179,13 @@ async function acquireWarmClaim({ repositoryRoot, phase, mode = phase === "refre
|
|
|
180
179
|
await sleep(pollMs);
|
|
181
180
|
}
|
|
182
181
|
} catch (error) {
|
|
183
|
-
releaseClaim(pending);
|
|
182
|
+
(0, ownership_claim_exports.releaseClaim)(pending);
|
|
184
183
|
if ([
|
|
185
184
|
"EACCES",
|
|
186
185
|
"EPERM",
|
|
187
186
|
"EROFS",
|
|
188
187
|
"ENOENT"
|
|
189
|
-
].includes(error?.code ?? "")) throw new ClaimUnavailableError(error.message, { claimPath: root });
|
|
188
|
+
].includes(error?.code ?? "")) throw new ownership_claim_exports.ClaimUnavailableError(error.message, { claimPath: root });
|
|
190
189
|
throw error;
|
|
191
190
|
}
|
|
192
191
|
}
|
|
@@ -883,7 +882,7 @@ function registerWarm(worktree) {
|
|
|
883
882
|
} catch (error) {
|
|
884
883
|
const code = error?.code;
|
|
885
884
|
console.error(chalk.red(`Could not warm this worktree: ${error.message}`));
|
|
886
|
-
const claim = claimFailure(error, `stim worktree warm${opts.refresh ? " --refresh" : ""}`);
|
|
885
|
+
const claim = (0, ownership_claim_exports.claimFailure)(error, `stim worktree warm${opts.refresh ? " --refresh" : ""}`);
|
|
887
886
|
if (claim) console.error(chalk.dim(claim.remedy));
|
|
888
887
|
if (typeof code === "string" && code.startsWith("STIM_")) console.error(chalk.red(`failed: ${code}`));
|
|
889
888
|
process.exitCode = 1;
|
|
@@ -1238,7 +1237,19 @@ async function runRemove(target, opts = {}) {
|
|
|
1238
1237
|
process.exitCode = 1;
|
|
1239
1238
|
return;
|
|
1240
1239
|
}
|
|
1241
|
-
if (
|
|
1240
|
+
if (entry.bare) {
|
|
1241
|
+
console.error(chalk.red(`Refusing to remove ${path}: ${entry.path} is the bare repository, not a worktree.`));
|
|
1242
|
+
console.error(chalk.dim(" Pass a worktree path, e.g. as printed by `git worktree list`."));
|
|
1243
|
+
process.exitCode = 1;
|
|
1244
|
+
return;
|
|
1245
|
+
}
|
|
1246
|
+
const source = sourceCheckoutOf(worktrees);
|
|
1247
|
+
if ("refusal" in source) {
|
|
1248
|
+
console.error(chalk.red(`Refusing to remove ${path}: ${source.refusal}`));
|
|
1249
|
+
process.exitCode = 1;
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
if (entry.path === source.path) {
|
|
1242
1253
|
if (entry.path !== path) console.error(chalk.dim(`${path} is inside the source checkout ${entry.path}; reclaiming its environment.`));
|
|
1243
1254
|
await reclaimEnvironment(entry.path, "it is the source checkout");
|
|
1244
1255
|
return;
|
|
@@ -1258,7 +1269,7 @@ async function runRemove(target, opts = {}) {
|
|
|
1258
1269
|
}
|
|
1259
1270
|
const deleteOwnedBranch = Boolean(ownsBranch && approvedBranchSha && inspection.unpushed?.length === 0);
|
|
1260
1271
|
const retainedBranchReason = !branch ? null : !ownsBranch ? "Stim did not create it" : inspection.unpushed === null ? "Stim could not verify whether it has unique commits" : inspection.unpushed.length > 0 ? `it has ${plural(inspection.unpushed.length, "unique commit")}` : null;
|
|
1261
|
-
const branchDeleteCwd =
|
|
1272
|
+
const branchDeleteCwd = source.path;
|
|
1262
1273
|
await withManagedRemoteWorktreeRemovalLock(path, () => withReclaimLocks(path, async (lockedKeys) => {
|
|
1263
1274
|
const result = await reclaimAll(path, lockedKeys, { preserveRootProject: true });
|
|
1264
1275
|
if (result.keptEntries.length) {
|
|
@@ -1290,13 +1301,6 @@ async function runRemove(target, opts = {}) {
|
|
|
1290
1301
|
worktreeRemovalComplete: true,
|
|
1291
1302
|
worktreePendingBranchSha: approvedBranchSha
|
|
1292
1303
|
});
|
|
1293
|
-
if (!branchDeleteCwd) {
|
|
1294
|
-
console.error(chalk.yellow(phaseLine("branch", `kept ${branch} (Stim could not find the source checkout)`)));
|
|
1295
|
-
console.error(chalk.dim(` Retry with: stim worktree remove ${path}`));
|
|
1296
|
-
process.exitCode = 1;
|
|
1297
|
-
finish();
|
|
1298
|
-
return;
|
|
1299
|
-
}
|
|
1300
1304
|
const checkedOutAt = listWorktrees(branchDeleteCwd).find((candidate) => candidate.branch === branch && resolve$1(candidate.path) !== resolve$1(path))?.path;
|
|
1301
1305
|
if (checkedOutAt) {
|
|
1302
1306
|
console.error(chalk.yellow(phaseLine("branch", `kept ${branch} (it is checked out at ${checkedOutAt})`)));
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as getExecutor } from "./exec-CyylIdq9.mjs";
|
|
2
|
-
import { g as loadConfig, u as getConfigDir } from "./config-
|
|
2
|
+
import { g as loadConfig, u as getConfigDir } from "./config-DMP7L7H6.mjs";
|
|
3
3
|
import { accessSync, chmodSync, constants, lstatSync, mkdirSync, mkdtempSync, readdirSync, realpathSync, rmSync, statSync } from "node:fs";
|
|
4
4
|
import { basename, dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
5
5
|
import { chmodSync as chmodSync$1, existsSync as existsSync$1, lstatSync as lstatSync$1, mkdirSync as mkdirSync$1, readFileSync as readFileSync$1, readdirSync as readdirSync$1, realpathSync as realpathSync$1, utimesSync } from "fs";
|
|
@@ -103,19 +103,6 @@ function gitCommonDir(cwd) {
|
|
|
103
103
|
]);
|
|
104
104
|
return out ? out.trim() : null;
|
|
105
105
|
}
|
|
106
|
-
function isMainWorkingTree(path) {
|
|
107
|
-
const out = getExecutor().runFileQuiet("git", [
|
|
108
|
-
"-C",
|
|
109
|
-
path,
|
|
110
|
-
"rev-parse",
|
|
111
|
-
"--path-format=absolute",
|
|
112
|
-
"--git-dir",
|
|
113
|
-
"--git-common-dir"
|
|
114
|
-
]);
|
|
115
|
-
if (!out) return false;
|
|
116
|
-
const [gitDir, commonDir] = out.trim().split("\n").map((line) => line.trim());
|
|
117
|
-
return Boolean(gitDir) && gitDir === commonDir;
|
|
118
|
-
}
|
|
119
106
|
function repoRoot(cwd) {
|
|
120
107
|
const out = getExecutor().runFileQuiet("git", [
|
|
121
108
|
"-C",
|
|
@@ -125,20 +112,49 @@ function repoRoot(cwd) {
|
|
|
125
112
|
]);
|
|
126
113
|
return out ? out.trim() : null;
|
|
127
114
|
}
|
|
115
|
+
function locallyKnownUpstream(projectRoot) {
|
|
116
|
+
try {
|
|
117
|
+
const name = getExecutor().runFile("git", [
|
|
118
|
+
"-C",
|
|
119
|
+
projectRoot,
|
|
120
|
+
"rev-parse",
|
|
121
|
+
"--abbrev-ref",
|
|
122
|
+
"--symbolic-full-name",
|
|
123
|
+
"@{upstream}"
|
|
124
|
+
], { timeoutMs: 5e3 });
|
|
125
|
+
const counts = getExecutor().runFile("git", [
|
|
126
|
+
"-C",
|
|
127
|
+
projectRoot,
|
|
128
|
+
"rev-list",
|
|
129
|
+
"--left-right",
|
|
130
|
+
"--count",
|
|
131
|
+
"HEAD...@{upstream}"
|
|
132
|
+
], { timeoutMs: 5e3 }).trim().split(/\s+/).map(Number);
|
|
133
|
+
const ahead = counts[0] ?? NaN;
|
|
134
|
+
const behind = counts[1] ?? NaN;
|
|
135
|
+
if (!name || !Number.isInteger(ahead) || !Number.isInteger(behind)) return null;
|
|
136
|
+
return {
|
|
137
|
+
name,
|
|
138
|
+
ahead,
|
|
139
|
+
behind
|
|
140
|
+
};
|
|
141
|
+
} catch {
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
128
145
|
function warmWorktreePaths(cwd) {
|
|
129
146
|
const currentRoot = repoRoot(cwd);
|
|
130
147
|
if (!currentRoot) throw new Error("Not a git repository.");
|
|
131
148
|
const target = realpathSync$1(currentRoot);
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
const
|
|
136
|
-
if (
|
|
137
|
-
const root = realpathSync$1(main.path);
|
|
149
|
+
const source = resolveSourceCheckout(target);
|
|
150
|
+
if ("refusal" in source) throw new Error(source.refusal);
|
|
151
|
+
if (!source.entries.find((entry) => canonicalPath(entry.path) === target)) throw new Error("Could not identify the linked worktree and its source checkout.");
|
|
152
|
+
const root = realpathSync$1(source.path);
|
|
153
|
+
if (root === target) throw new Error("Run stim worktree warm from a linked worktree, not the source checkout.");
|
|
138
154
|
const sourceRoot = repoRoot(root);
|
|
139
155
|
const sourceCommon = gitCommonDir(root);
|
|
140
156
|
const targetCommon = gitCommonDir(target);
|
|
141
|
-
if (
|
|
157
|
+
if (!sourceRoot || realpathSync$1(sourceRoot) !== root || !sourceCommon || !targetCommon || realpathSync$1(sourceCommon) !== realpathSync$1(targetCommon)) throw new Error("Could not verify that the source checkout belongs to this linked worktree.");
|
|
142
158
|
return {
|
|
143
159
|
root,
|
|
144
160
|
target,
|
|
@@ -526,6 +542,7 @@ function parseWorktrees(out) {
|
|
|
526
542
|
current = { path: line.slice(9) };
|
|
527
543
|
} else if (line.startsWith("branch ")) current.branch = line.slice(7).replace("refs/heads/", "");
|
|
528
544
|
else if (line === "prunable" || line.startsWith("prunable ")) current.prunable = true;
|
|
545
|
+
else if (line === "bare") current.bare = true;
|
|
529
546
|
if (current.path) entries.push(current);
|
|
530
547
|
return entries;
|
|
531
548
|
}
|
|
@@ -539,5 +556,45 @@ function listWorktrees(cwd) {
|
|
|
539
556
|
]);
|
|
540
557
|
return out ? parseWorktrees(out) : [];
|
|
541
558
|
}
|
|
559
|
+
function selectSourceCheckout(entries, bareHead) {
|
|
560
|
+
const first = entries[0];
|
|
561
|
+
if (!first) return { refusal: "Git lists no worktrees for this repository." };
|
|
562
|
+
if (!first.bare) return { path: first.path };
|
|
563
|
+
const bare = first.path;
|
|
564
|
+
const checkouts = entries.filter((entry) => !entry.bare && !entry.prunable);
|
|
565
|
+
const listed = checkouts.map((entry) => `${entry.branch ?? "detached"} (${entry.path})`).join(", ") || "none";
|
|
566
|
+
const pointHead = ` git -C ${bare} symbolic-ref HEAD refs/heads/<branch>`;
|
|
567
|
+
if (!bareHead) return { refusal: `The bare repository at ${bare} has a detached HEAD, so Stim cannot tell which worktree is the source checkout. Point HEAD at the source branch, then retry:\n${pointHead}\nChecked-out branches: ${listed}` };
|
|
568
|
+
const matches = checkouts.filter((entry) => entry.branch === bareHead);
|
|
569
|
+
const [only] = matches;
|
|
570
|
+
if (only && matches.length === 1) return { path: only.path };
|
|
571
|
+
if (!only) {
|
|
572
|
+
const stale = entries.find((entry) => entry.prunable && entry.branch === bareHead);
|
|
573
|
+
const beside = checkouts[0] ? dirname$1(checkouts[0].path) : bare;
|
|
574
|
+
return { refusal: `The bare repository at ${bare} points HEAD at ${bareHead}, but no worktree has ${bareHead} checked out, so Stim has no source checkout to copy from. ${stale ? `Its worktree at ${stale.path} is missing. Recreate it, then retry:\n git -C ${bare} worktree prune\n git -C ${bare} worktree add ${stale.path} ${bareHead}\n` : `Create one, then retry:\n git -C ${bare} worktree add ${join$1(beside, bareHead)} ${bareHead}\n`}Or point HEAD at a branch that is checked out (${listed}):\n${pointHead}` };
|
|
575
|
+
}
|
|
576
|
+
return { refusal: `The bare repository at ${bare} points HEAD at ${bareHead}, which is checked out in more than one worktree: ${matches.map((entry) => entry.path).join(", ")}. Remove the extra worktrees, or point HEAD at a branch checked out once, then retry:\n${pointHead}` };
|
|
577
|
+
}
|
|
578
|
+
function bareHeadBranch(bare) {
|
|
579
|
+
const out = getExecutor().runFileQuiet("git", [
|
|
580
|
+
"-C",
|
|
581
|
+
bare,
|
|
582
|
+
"symbolic-ref",
|
|
583
|
+
"--quiet",
|
|
584
|
+
"HEAD"
|
|
585
|
+
])?.trim();
|
|
586
|
+
return out?.startsWith("refs/heads/") ? out.slice(11) : null;
|
|
587
|
+
}
|
|
588
|
+
function sourceCheckoutOf(entries) {
|
|
589
|
+
const first = entries[0];
|
|
590
|
+
return selectSourceCheckout(entries, first?.bare ? bareHeadBranch(first.path) : null);
|
|
591
|
+
}
|
|
592
|
+
function resolveSourceCheckout(cwd) {
|
|
593
|
+
const entries = listWorktrees(cwd);
|
|
594
|
+
return {
|
|
595
|
+
entries,
|
|
596
|
+
...sourceCheckoutOf(entries)
|
|
597
|
+
};
|
|
598
|
+
}
|
|
542
599
|
//#endregion
|
|
543
|
-
export {
|
|
600
|
+
export { filesystemDevice as C, temporaryRoot as E, warmWorktreePaths as S, removeTemporaryEntry as T, resolveFullRef as _, dirtyFingerprintFiles as a, sourceCheckoutOf as b, hasRemote as c, listWorktrees as d, locallyKnownUpstream as f, repoRoot as g, removeWorktree as h, depsOutOfSync as i, hasUncommittedWork as l, readWorktreeExclude as m, cloneIgnoredEntries as n, dirtyPaths as o, podsOutOfSync as p, deleteBranch as r, gitCommonDir as s, branchExists as t, isPodInstallChurn as u, resolveSourceCheckout as v, makeTemporaryDirectory as w, unpushedCommits as x, restoreFile as y };
|