Skip to content

fix(git): clean exact prepared branches after finalization failure - #35333

Closed
OrcaWin wants to merge 1 commit into
OrcaWin/git-canonical-current-branchfrom
OrcaWin/git-prepared-finalization-identity
Closed

OrcaWin wants to merge 1 commit into
OrcaWin/git-canonical-current-branchfrom
OrcaWin/git-prepared-finalization-identity

Conversation

@OrcaWin

@OrcaWin OrcaWin commented Oct 28, 2026 •

Copy link
Copy Markdown
Collaborator
Files Added Deleted Net
Test 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​110 0 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​110
Prod 1 $\color{#1a7f37}{\Huge{\mathbf{+}}}$​8 $\color{#cf222e}{\Huge{\mathbf{−}}}$​9 $\color{#cf222e}{\Huge{\mathbf{−}}}$​1

A failed prepared-worktree creation can remove its checkout but leave the newly created branch behind when a tag has the same name. symbolic-ref --short HEAD disambiguates feature as heads/feature, so rollback no longer recognizes the branch it just attached. A real heads/feature branch with a matching tag has the same failure.

Reuse the full symbolic-HEAD reader from prerequisite #35040 for this remaining rollback consumer. Compare its exact branch name before the existing owned-checkout removal, then retain the existing conditional branch deletion. Fence this parsed command's WSL login output through the existing capture option. No additional subprocess, filesystem operation, timer, cache, wire field or saved data is introduced.

Evidence and validation

  • The public prepareWorktreeCreateCheckout and finalizePreparedWorktree flows run against actual Git 2.25.5 and 2.55.0. A real executable post-checkout hook exits 23 after Git creates the branch, exercising ordinary failure cleanup without injecting a Git result or replacing the removal path. Each version is asserted through the production runner. Only observability is replaced in the external proof.
  • For each version, ordinary feature cleans its branch on both versions of the code. A same-name feature tag and a real heads/feature branch with a same-name tag each retain the branch on the parent and remove it after the fix. In all three cases the owned failed checkout registration is removed. A hook that switches to another branch preserves the newly created branch, and a hook that replaces the preparation lock preserves both branch and checkout. All 20 before/after public outcomes are asserted. Main HEAD, index and tracked file bytes remain unchanged; fixtures are removed.
  • The new checked-in real-Git regression fails exactly the two tag-collision cases on the parent while four controls pass. It additionally covers a hook detaching HEAD, tag object IDs, the other branch's object ID, foreign lock contents and retained checkout bytes. Its executable shell-hook fixture skips native Windows; the production full-ref reader and existing Windows/WSL forwarding controls remain portable.
  • Focused validation passes 33 tests across three suites on current Git and 32 tests with one existing version-gated skip on Git 2.25, under explicit Node 24. Targeted lint and formatting pass. Independent source/evidence review found no remaining blocker at frozen tree a6254dd186c0cffee452c7ee7552bc0d7cd2ad29. Required pnpm check:changed --base=2d3e7e452000c26433650d75422e79a06be80684 --maxWorkers=2 selected 15 files and passed 21 of 23 checks. Catalog validation fails on three Turkish-only queued-message keys; the catalogs and validators byte-match the pinned baseline. The related-test selection was stopped after 600.65 seconds without an aggregate test summary or individual failure output. All four owned descendants were verified by ancestry/start time and exited. The gate exited 1 after 608.91 seconds; no complete broad-suite pass is claimed.

Reachability and integration

Prepared workspace finalization attaches the new branch after moving the owned checkout. Checkout hooks, metadata/config writes, or other subsequent failures enter this existing rollback path. This change retains the fresh ownership-lock checks, double-force eligibility, removal-success condition, detached/unreadable handling, cleanup deadline and cancellation policy. It does not authorize cleanup after a competing owner takes over. The original finalization error still reaches its caller.

Stacked on #35040 because it supplies the existing exact branch-name reader; that PR changes history/upstream consumers but leaves this private short-name query. The rollback query was introduced with #24346 and predates the pinned base. Bounded open-PR searches for prepared-branch and finalization cleanup found no matching correction; this is a scoped search, not an exhaustive duplicate guarantee. Preserve independent preparation-lock and finalization safety work when integrating.

Linux with both Git versions is verified. Native Windows/WSL/macOS, live SSH, physical mobile, Electron and a packaged build were not run. Execution hosts need this backend fix where they perform prepared finalization. Folder-only workspaces do not enter this Git preparation path. The proof concerns rollback correctness, with no measured latency or whole-app RAM claim. Screenshots are not applicable to the backend identity change; public outcomes are recorded directly.

@OrcaWin

OrcaWin commented Oct 30, 2026

Copy link
Copy Markdown
Collaborator Author

Closing: this needs a worktree finalization failure after checkout -b and, at the same time, a tag with exactly the same name, and the only result is an orphaned branch ref. That does not justify a stacked dependency, a 110-line real-git test and an unrelated WSL capture change. If wanted, it is a one-line inline symbolic-ref --quiet HEAD vs refs/heads/<branch> change.

@OrcaWin OrcaWin closed this Oct 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant