fix: create fresh branch from parent when parent differs from current branch#98
Merged
Conversation
dansimau
marked this pull request as ready for review
June 5, 2026 09:13
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 48432d5e2e
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
dansimau
added a commit
that referenced
this pull request
Jun 5, 2026
## Summary
CI on `main` intermittently fails due to **two independent pre-existing
flaky tests** that surface under parallel test execution. Both are
unrelated to any product behaviour change; this PR makes them
deterministic. (Discovered while a separate PR's CI kept going red on
unrelated tests.)
### Flake 1 — `TestWorktree_RestackAllStaysOnCorrectBranchOnConflict`
`buildRestackWorkQueue` (pkg/yas/restack.go) iterated child branches by
ranging over the **map** returned by `graph.GetChildren`, so the restack
work-queue order was non-deterministic. When restacking multiple
siblings, if a sibling that conflicts was processed before one that
rebases cleanly, the clean branch never got rebased — and the test's
assertion (`main-1` should be in `topic-a`'s history) failed.
**Fix:** collect child IDs and iterate them in sorted order, giving
stable, repeatable restack ordering.
### Flake 2 — "text file busy" (ETXTBSY) in `testutil.ExecOrFail`
The helper wrote a temp `.sh`, ran `chmod +x`, then `sh -c <path>` —
which **execs** the script file. Under parallel tests, another
goroutine's `fork+exec` can transiently inherit the temp file's
still-open writable descriptor, so the kernel returns `ETXTBSY` ("text
file busy") when `sh` tries to exec it. This is the classic Go
write-then-exec-in-parallel race and can hit *any* test using this
helper (observed on `TestDelete_RefusesToDeleteTrunkBranch`).
**Fix:** invoke `sh <path>` so the shell **opens and reads** the script
rather than exec'ing the file, sidestepping the race. The
now-unnecessary `chmod +x` is removed.
## Testing
On clean `main`, the full integration suite failed ~2 of every 3 runs
(worktree flake) plus occasional ETXTBSY failures. With these fixes:
- Full integration suite: **5/5 green**
- `TestWorktree_RestackAllStaysOnCorrectBranchOnConflict` +
`TestDelete*`: **10/10 green**
- `go test ./pkg/...`: pass
- `golangci-lint`: 0 issues
## Notes
This is a standalone stabilization PR. It is independent of #98 (which
makes `yas branch --parent` create a fresh branch from the parent);
#98's CI was red only because of these flakes. Merging this should make
CI reliable for #98 and others.
https://claude.ai/code/session_01TQQ48xS5k2AXR2xF4tDKb8
---
_Generated by [Claude
Code](https://claude.ai/code/session_01TQQ48xS5k2AXR2xF4tDKb8)_
Co-authored-by: Claude <noreply@anthropic.com>
… branch When running 'yas branch --parent <branch>' with a parent that differs from the current branch, create the new branch based on the parent's HEAD rather than the current HEAD. In this case, staged changes from the current branch are no longer committed onto the new branch. https://claude.ai/code/session_01TQQ48xS5k2AXR2xF4tDKb8
Address two edge cases in the createFromParent path: - Detached HEAD with an explicit --parent no longer fails. The current branch name is only needed when no parent is given, so it is now fetched unconditionally only in that case and treated as best-effort otherwise. - A parent that exists only remotely (origin/<parent> with no local branch) is now resolved to its remote-tracking ref as the branch start point, mirroring the existing origin/ fallback in SetParent. Adds tests for both scenarios.
dansimau
force-pushed
the
claude/relaxed-sagan-sWmvs
branch
from
June 5, 2026 09:29
bc08e6c to
8de0515
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
When running
yas branch --parent <branch>(akayas br --parent <branch>) where the specified parent is different from the current branch, yas now creates a fresh branch based on the parent's HEAD instead of branching from the currentHEAD.Previously,
CreateBranchalways rangit checkout -b <new>from wherever you currently were, and then auto-committed any staged changes onto the new branch. This meant--parentonly set the recorded parent metadata but the branch contents were still based on the current branch (including any staged files getting committed).Behaviour change
--parentis given and differs from the current branch: create the branch viagit checkout -b <new> <parent>(a fresh branch off the parent), and do not carry over / commit staged changes.--parentis omitted or equals the current branch: unchanged behaviour (branch off current HEAD, auto-commit staged changes).Changes
pkg/gitexec/gitexec.go: addCreateBranchFrom(branch, startPoint)helper.pkg/yas/yas.go: inCreateBranch, base the new branch on the parent when it differs from the current branch, and skip the staged-changes auto-commit in that case.test/branch_create_test.go: addTestBranchCreate_WithDifferentParentBranchesFromParentverifying the new branch is based on the parent's HEAD and that current/staged files are not carried over.Testing
go test ./test -run TestBranchCreate✅go test ./pkg/yas ./pkg/gitexec✅make lint✅ (0 issues)https://claude.ai/code/session_01TQQ48xS5k2AXR2xF4tDKb8
Generated by Claude Code