hillclimb 0.8.13 → 0.9.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.
|
@@ -160,7 +160,7 @@ async function repoIdentity(repoRoot) {
|
|
|
160
160
|
}
|
|
161
161
|
async function logHeal(level, message) {
|
|
162
162
|
try {
|
|
163
|
-
const { appendLog: appendLog2 } = await import("./log-
|
|
163
|
+
const { appendLog: appendLog2 } = await import("./log-6OIO3F7C.js");
|
|
164
164
|
appendLog2(level, message);
|
|
165
165
|
} catch {
|
|
166
166
|
}
|
|
@@ -169,11 +169,11 @@ function matchByPath(projects, resolved) {
|
|
|
169
169
|
let best = null;
|
|
170
170
|
let bestLen = -1;
|
|
171
171
|
for (const [key, config] of Object.entries(projects)) {
|
|
172
|
-
const
|
|
173
|
-
if (resolved ===
|
|
174
|
-
if (
|
|
175
|
-
bestLen =
|
|
176
|
-
best = { key, repoRoot:
|
|
172
|
+
const canonical2 = path.resolve(key);
|
|
173
|
+
if (resolved === canonical2 || resolved.startsWith(canonical2 + path.sep)) {
|
|
174
|
+
if (canonical2.length > bestLen) {
|
|
175
|
+
bestLen = canonical2.length;
|
|
176
|
+
best = { key, repoRoot: canonical2, config };
|
|
177
177
|
}
|
|
178
178
|
}
|
|
179
179
|
}
|
|
@@ -192,6 +192,10 @@ async function healRenamedProject(file, resolved) {
|
|
|
192
192
|
healMisses.add(missKey);
|
|
193
193
|
return null;
|
|
194
194
|
}
|
|
195
|
+
if (await linkedWorktreeParent(toplevel)) {
|
|
196
|
+
healMisses.add(missKey);
|
|
197
|
+
return null;
|
|
198
|
+
}
|
|
195
199
|
const repoRoot = path.resolve(toplevel);
|
|
196
200
|
const identity = await repoIdentity(repoRoot);
|
|
197
201
|
const strong = dead.filter(([, config2]) => {
|
|
@@ -246,6 +250,44 @@ async function backfillIdentity(file, match) {
|
|
|
246
250
|
if (identity.remoteUrl) stored.remoteUrl = identity.remoteUrl;
|
|
247
251
|
await saveProjects(file);
|
|
248
252
|
}
|
|
253
|
+
async function canonical(target) {
|
|
254
|
+
try {
|
|
255
|
+
return await fs.promises.realpath(target);
|
|
256
|
+
} catch {
|
|
257
|
+
return path.resolve(target);
|
|
258
|
+
}
|
|
259
|
+
}
|
|
260
|
+
async function linkedWorktreeParent(toplevel) {
|
|
261
|
+
const [gitDir, commonDir] = await Promise.all([
|
|
262
|
+
gitOut(["rev-parse", "--git-dir"], toplevel),
|
|
263
|
+
gitOut(["rev-parse", "--git-common-dir"], toplevel)
|
|
264
|
+
]);
|
|
265
|
+
if (!gitDir || !commonDir) return null;
|
|
266
|
+
const absolute = (value) => path.isAbsolute(value) ? value : path.join(toplevel, value);
|
|
267
|
+
const [ownDir, sharedDir] = await Promise.all([
|
|
268
|
+
canonical(absolute(gitDir)),
|
|
269
|
+
canonical(absolute(commonDir))
|
|
270
|
+
]);
|
|
271
|
+
if (ownDir === sharedDir || path.basename(sharedDir) !== ".git") return null;
|
|
272
|
+
return {
|
|
273
|
+
worktreeRoot: path.resolve(toplevel),
|
|
274
|
+
parentRoot: path.dirname(sharedDir)
|
|
275
|
+
};
|
|
276
|
+
}
|
|
277
|
+
async function matchLinkedWorktree(projects, resolved) {
|
|
278
|
+
const toplevel = await gitOut(["rev-parse", "--show-toplevel"], resolved);
|
|
279
|
+
if (!toplevel) return null;
|
|
280
|
+
const linked = await linkedWorktreeParent(toplevel);
|
|
281
|
+
if (!linked) return null;
|
|
282
|
+
const direct = matchByPath(projects, linked.parentRoot);
|
|
283
|
+
if (direct) return { repoRoot: linked.worktreeRoot, config: direct.config };
|
|
284
|
+
const parentRoot = await canonical(linked.parentRoot);
|
|
285
|
+
for (const [key, config] of Object.entries(projects)) {
|
|
286
|
+
if (await canonical(key) === parentRoot)
|
|
287
|
+
return { repoRoot: linked.worktreeRoot, config };
|
|
288
|
+
}
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
249
291
|
async function findProjectForCwd(cwd) {
|
|
250
292
|
const file = await loadProjects();
|
|
251
293
|
const resolved = path.resolve(cwd);
|
|
@@ -254,6 +296,8 @@ async function findProjectForCwd(cwd) {
|
|
|
254
296
|
await backfillIdentity(file, match);
|
|
255
297
|
return { repoRoot: match.repoRoot, config: match.config };
|
|
256
298
|
}
|
|
299
|
+
const worktree = await matchLinkedWorktree(file.projects, resolved);
|
|
300
|
+
if (worktree) return worktree;
|
|
257
301
|
return healRenamedProject(file, resolved);
|
|
258
302
|
}
|
|
259
303
|
|