Skip to content

fix: create fresh branch from parent when parent differs from current branch#98

Merged
dansimau merged 3 commits into
mainfrom
claude/relaxed-sagan-sWmvs
Jun 5, 2026
Merged

fix: create fresh branch from parent when parent differs from current branch#98
dansimau merged 3 commits into
mainfrom
claude/relaxed-sagan-sWmvs

Conversation

@dansimau

@dansimau dansimau commented Jun 5, 2026

Copy link
Copy Markdown
Owner

Summary

When running yas branch --parent <branch> (aka yas 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 current HEAD.

Previously, CreateBranch always ran git checkout -b <new> from wherever you currently were, and then auto-committed any staged changes onto the new branch. This meant --parent only set the recorded parent metadata but the branch contents were still based on the current branch (including any staged files getting committed).

Behaviour change

  • If --parent is given and differs from the current branch: create the branch via git checkout -b <new> <parent> (a fresh branch off the parent), and do not carry over / commit staged changes.
  • If --parent is omitted or equals the current branch: unchanged behaviour (branch off current HEAD, auto-commit staged changes).

Changes

  • pkg/gitexec/gitexec.go: add CreateBranchFrom(branch, startPoint) helper.
  • pkg/yas/yas.go: in CreateBranch, 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: add TestBranchCreate_WithDifferentParentBranchesFromParent verifying 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

@dansimau
dansimau marked this pull request as ready for review June 5, 2026 09:13

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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".

Comment thread pkg/yas/yas.go Outdated
Comment thread pkg/yas/yas.go Outdated
Comment thread pkg/yas/yas.go Outdated
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>
claude added 3 commits June 5, 2026 09:28
… 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
dansimau force-pushed the claude/relaxed-sagan-sWmvs branch from bc08e6c to 8de0515 Compare June 5, 2026 09:29
@dansimau
dansimau merged commit cb51d41 into main Jun 5, 2026
1 check passed
@dansimau
dansimau deleted the claude/relaxed-sagan-sWmvs branch June 5, 2026 09:40
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.

2 participants