Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions cmd/push.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,22 @@ func runPush(cmd *cobra.Command, args []string) error {
branches[i], branches[j] = branches[j], branches[i]
}

// Validate all branches are properly rebased onto their parents
for _, b := range branches {
parent, _ := cfg.GetParent(b.Name) //nolint:errcheck // empty string is fine
if parent == "" {
continue
}

needsRebase, err := g.NeedsRebase(b.Name, parent)
if err != nil {
return fmt.Errorf("failed to check rebase status for %s: %w", b.Name, err)
}
if needsRebase {
return fmt.Errorf("branch %q is not rebased onto %q; run 'gh stack cascade' first", b.Name, parent)
}
}

// Update PR bases and push
for _, b := range branches {
parent, _ := cfg.GetParent(b.Name) //nolint:errcheck // empty string is fine
Expand Down
33 changes: 33 additions & 0 deletions e2e/push_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,3 +40,36 @@ func TestPushStack(t *testing.T) {
t.Errorf("stack not fully pushed: %s", remoteBranches)
}
}

func TestPushFailsWhenNotRebased(t *testing.T) {
env := NewTestEnvWithRemote(t)
env.MustRun("init")

// Create stack: main -> feat-a -> feat-b
env.MustRun("create", "feat-a")
env.CreateCommit("a work")

env.MustRun("create", "feat-b")
env.CreateCommit("b work")

// Go back to feat-a and add a new commit
// This makes feat-b no longer rebased onto feat-a
env.Git("checkout", "feat-a")
env.CreateCommit("more a work")

// Go to feat-b and try to push - should fail
env.Git("checkout", "feat-b")
result := env.Run("push")

if result.Success() {
t.Error("expected push to fail when branch is not rebased")
}

if !strings.Contains(result.Stderr, "not rebased onto") {
t.Errorf("expected error about rebase, got: %s", result.Stderr)
}

if !strings.Contains(result.Stderr, "gh stack cascade") {
t.Errorf("expected error to mention 'gh stack cascade', got: %s", result.Stderr)
}
}
Loading