* test(#3207): invert fresh-create branching tests to expect create+switch The four fresh-create branching tests (#3079) locked in create-without- switch behavior that #3207 identifies as the regression: a fresh phase/ milestone branch is created but HEAD never moves onto it, so the first phase/milestone-scoped commit lands on the base branch. Invert those assertions to expect create+switch, and add two new tests: - fresh-create is non-silent (logs the create+switch) (#3207 AC3) - a second phase commit does not re-warn once HEAD is on the phase branch (#3207 AC5) The existing-branch path (#2539) is deliberately byte-for-byte unchanged. RED — fails on next; the fix follows in a separate fix: commit. * fix(#3207): create-and-switch on the first phase/milestone commit The #3079 fix (PR #3141) replaced git checkout -b with git branch (create-only) unconditionally, including the case where the strategy branch does not yet exist. That regressed #1278: the first phase- or milestone-scoped commit no longer landed on the strategy branch — it stayed on the base branch, and the strategy branch was left as an empty marker pointing at the pre-phase tip. Every subsequent commit then warned 'already exists; committing on the current branch instead of switching', wording that misleads because the tool itself created the branch moments before. Re-separate the two cases #3079 collapsed: - branch does NOT exist -> create AND switch (git checkout -b). The #3079 resurrection hazard cannot apply: the branch was just verified absent, so there is no merged-and-deleted ref to resurrect and no silent move onto an existing unrelated branch (#2539 AC2 is honored by the existing-branch arm, which is unchanged). The create is logged so the first phase-scoped commit is not silent (#3207 AC3). - branch ALREADY exists -> unchanged: no switch, commit on current branch, non-silent warning (#2539/#3079). Once the first commit switches HEAD onto the strategy branch, the currentBranch !== branchName guard skips the block on subsequent commits, so the misleading 'already exists' warning no longer recurs. * chore(#3207): add changeset fragment * chore(#3207): backfill changeset PR number (#3363) --------- Co-authored-by: sim <sim@local>
This commit is contained in:
@@ -1052,22 +1052,29 @@ function cmdCommit(cwd: string, message: string | undefined, files: string[] | u
|
||||
if (branchName) {
|
||||
const currentBranch = execGit(['rev-parse', '--abbrev-ref', 'HEAD'], { cwd });
|
||||
if (currentBranch.exitCode === 0 && currentBranch.stdout.trim() !== branchName) {
|
||||
// #2539/#3079: the #1278 intent is to CREATE the phase/milestone branch
|
||||
// before the FIRST commit on it — not to force-switch an already-
|
||||
// checked-out working branch onto a DIFFERENT existing branch. The
|
||||
// prior `git checkout -b` both created AND switched (silently moving
|
||||
// HEAD), which resurrected merged-and-deleted phase branches (#3079).
|
||||
// Now: create-if-absent WITHOUT switching, using `git branch` instead
|
||||
// of `git checkout -b`. The commit always lands on the current branch.
|
||||
// If the resolved branch already exists, log the resolution so the
|
||||
// operator sees that the phase branch was resolved and deliberately
|
||||
// not switched to (#2539 AC2: an auto-checkout mid-commit must never
|
||||
// happen silently).
|
||||
// #2539/#3079/#3207: two cases the prior (#3079) code collapsed into one.
|
||||
// #1278 intent: CREATE the phase/milestone branch before the FIRST commit
|
||||
// on it so the phase's work accumulates there. #3079/#2539 hazard: never
|
||||
// silently switch an already-checked-out working branch onto a DIFFERENT
|
||||
// EXISTING branch — that resurrects merged-and-deleted phase branches and
|
||||
// silently moves HEAD onto a stale ref (#2539 AC2: an auto-checkout
|
||||
// mid-commit must never happen silently).
|
||||
// Reconciliation (#3207): a brand-new branch has no resurrection target,
|
||||
// so create-and-switch is safe here and is exactly the #1278 intent; an
|
||||
// EXISTING branch is never switched to (the else arm logs + commits in
|
||||
// place). The fresh create is logged so the first phase-scoped commit is
|
||||
// not silent about where the work is landing (#3207 AC3).
|
||||
const verify = execGit(['rev-parse', '--verify', `refs/heads/${branchName}`], { cwd });
|
||||
if (verify.exitCode !== 0) {
|
||||
// Branch does not exist — create it WITHOUT switching.
|
||||
const create = execGit(['branch', branchName], { cwd });
|
||||
if (create.exitCode !== 0) {
|
||||
// Branch does not exist — CREATE AND SWITCH (the #1278 first-commit
|
||||
// case). checkout -b cannot resurrect anything: the branch was just
|
||||
// verified absent, so it is created fresh at HEAD.
|
||||
const create = execGit(['checkout', '-b', branchName], { cwd });
|
||||
if (create.exitCode === 0) {
|
||||
process.stderr.write(
|
||||
`${branchingStrategy} branch "${branchName}" created; switched to it for this commit.\n`
|
||||
);
|
||||
} else {
|
||||
process.stderr.write(
|
||||
`Warning: could not create ${branchingStrategy} branch "${branchName}" ` +
|
||||
`(${create.stderr.trim()}); committing on the current branch "${currentBranch.stdout.trim()}".\n`
|
||||
|
||||
Reference in New Issue
Block a user