mirror of
https://github.com/garrytan/gstack.git
synced 2026-09-11 07:29:00 +02:00
fix(bins): Windows-safe GIT_CEILING join; next-version probes the full default-base chain
GIT_CEILING_DIRECTORIES was joined with ':' — git on Windows splits on ';' and drive letters contain ':', silently disabling the #2144 second-layer defense there; now path.delimiter. next-version's default-base detection only tried origin/HEAD then 'main', diverging from the canonical 4-step chain diff-scope uses — origin/main and origin/master probes added, pinned by fixture repos.
This commit is contained in:
@@ -54,7 +54,7 @@ import {
|
||||
rmSync,
|
||||
realpathSync,
|
||||
} from "fs";
|
||||
import { join, basename, dirname } from "path";
|
||||
import { join, basename, dirname, delimiter } from "path";
|
||||
import { execFileSync, spawnSync, spawn, type ChildProcess } from "child_process";
|
||||
import { homedir } from "os";
|
||||
import { createHash } from "crypto";
|
||||
@@ -1443,8 +1443,10 @@ function runGbrainImport(
|
||||
}
|
||||
const baseEnv: NodeJS.ProcessEnv = {
|
||||
...process.env,
|
||||
// path.delimiter, not ':' — git splits this on ';' on Windows, and
|
||||
// drive-letter paths contain ':' themselves.
|
||||
GIT_CEILING_DIRECTORIES: process.env.GIT_CEILING_DIRECTORIES
|
||||
? `${ceiling}:${process.env.GIT_CEILING_DIRECTORIES}`
|
||||
? `${ceiling}${delimiter}${process.env.GIT_CEILING_DIRECTORIES}`
|
||||
: ceiling,
|
||||
};
|
||||
const child = spawnGbrainAsync(
|
||||
|
||||
+19
-3
@@ -407,13 +407,29 @@ function parseArgs(argv: string[]): { base: string; bump: Bump; current: string;
|
||||
if (help) return { base: "", bump: "micro", current: "", excludePR: null, help: true };
|
||||
if (!base) {
|
||||
// Detect the default branch instead of assuming main (local-only repos
|
||||
// on trunk/master work like GitHub repos on main).
|
||||
// on trunk/master work like GitHub repos on main). Same probe order as
|
||||
// the canonical chain in bin/gstack-diff-scope and {{BASE_BRANCH_DETECT}}
|
||||
// (scripts/resolvers/utility.ts): origin/HEAD -> origin/main ->
|
||||
// origin/master -> literal "main". origin/HEAD is unset on plain clones
|
||||
// that never ran `git remote set-head`, so the rev-parse probes matter.
|
||||
try {
|
||||
const head = execFileSync("git", ["symbolic-ref", "refs/remotes/origin/HEAD"], { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }).trim();
|
||||
base = head.replace("refs/remotes/origin/", "") || "main";
|
||||
base = head.replace("refs/remotes/origin/", "");
|
||||
} catch {
|
||||
base = "main";
|
||||
// fall through to the rev-parse probes
|
||||
}
|
||||
if (!base) {
|
||||
for (const candidate of ["main", "master"]) {
|
||||
try {
|
||||
execFileSync("git", ["rev-parse", "--verify", "-q", `origin/${candidate}`], { stdio: ["ignore", "ignore", "ignore"] });
|
||||
base = candidate;
|
||||
break;
|
||||
} catch {
|
||||
// probe failed; try the next candidate
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!base) base = "main";
|
||||
}
|
||||
if (!bump) {
|
||||
console.error("Error: --bump is required (major|minor|patch|micro)");
|
||||
|
||||
Reference in New Issue
Block a user