Skip to content

Commit 86d342e

Browse files
committed
delete stack locally
1 parent ad9d170 commit 86d342e

3 files changed

Lines changed: 96 additions & 0 deletions

File tree

cmd/root.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ func RootCmd() *cobra.Command {
2828
// Remote operations
2929
root.AddCommand(CheckoutCmd(cfg))
3030
root.AddCommand(PushCmd(cfg))
31+
root.AddCommand(UnstackCmd(cfg))
3132
root.AddCommand(MergeCmd(cfg))
3233

3334
// Helper commands

cmd/unstack.go

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
package cmd
2+
3+
import (
4+
"github.com/github/gh-stack/internal/config"
5+
"github.com/github/gh-stack/internal/git"
6+
"github.com/github/gh-stack/internal/stack"
7+
"github.com/spf13/cobra"
8+
)
9+
10+
type unstackOptions struct {
11+
target string
12+
local bool
13+
}
14+
15+
func UnstackCmd(cfg *config.Config) *cobra.Command {
16+
opts := &unstackOptions{}
17+
18+
cmd := &cobra.Command{
19+
Use: "unstack [branch]",
20+
Short: "Delete a stack locally and on GitHub",
21+
Long: "Remove a stack from local tracking and delete it on GitHub. Use --local to only remove local tracking.",
22+
Args: cobra.MaximumNArgs(1),
23+
RunE: func(cmd *cobra.Command, args []string) error {
24+
if len(args) > 0 {
25+
opts.target = args[0]
26+
}
27+
return runUnstack(cfg, opts)
28+
},
29+
}
30+
31+
cmd.Flags().BoolVar(&opts.local, "local", false, "Only delete the stack locally")
32+
33+
return cmd
34+
}
35+
36+
func runUnstack(cfg *config.Config, opts *unstackOptions) error {
37+
gitDir, err := git.GitDir()
38+
if err != nil {
39+
cfg.Errorf("not a git repository")
40+
return nil
41+
}
42+
43+
sf, err := stack.Load(gitDir)
44+
if err != nil {
45+
cfg.Errorf("failed to load stack state: %s", err)
46+
return nil
47+
}
48+
49+
target := opts.target
50+
if target == "" {
51+
target, err = git.CurrentBranch()
52+
if err != nil {
53+
cfg.Errorf("unable to determine current branch: %s", err)
54+
return nil
55+
}
56+
}
57+
58+
s := sf.FindStackForBranch(target)
59+
if s == nil {
60+
cfg.Errorf("branch %q is not part of a stack", target)
61+
return nil
62+
}
63+
64+
cfg.Printf("Stack branches: %v", s.BranchNames())
65+
66+
// Remove from local tracking
67+
sf.RemoveStackForBranch(target)
68+
if err := stack.Save(gitDir, sf); err != nil {
69+
cfg.Errorf("failed to save stack state: %s", err)
70+
return nil
71+
}
72+
cfg.Successf("Stack removed from local tracking")
73+
74+
// Delete the stack on GitHub
75+
if !opts.local {
76+
client, err := cfg.GitHubClient()
77+
if err != nil {
78+
cfg.Errorf("failed to create GitHub client: %s", err)
79+
return nil
80+
}
81+
if err := client.DeleteStack(); err != nil {
82+
cfg.Warningf("%v", err)
83+
} else {
84+
cfg.Successf("Stack deleted on GitHub")
85+
}
86+
}
87+
88+
return nil
89+
}

internal/github/github.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,12 @@ func (c *Client) UpdatePRBase(prID, newBase string) error {
169169
return c.gql.Mutate("UpdatePullRequest", &mutation, variables)
170170
}
171171

172+
// DeleteStack deletes a stack on GitHub.
173+
// TODO: Implement once the stack API is available.
174+
func (c *Client) DeleteStack() error {
175+
return fmt.Errorf("deleting a stack on GitHub is not yet supported by the API")
176+
}
177+
172178
func (c *Client) repositoryID() (string, error) {
173179
var query struct {
174180
Repository struct {

0 commit comments

Comments
 (0)