@@ -86,6 +86,7 @@ def __init__(self) -> None:
86
86
self .gitstack = read_gitstack_file ()
87
87
self .gitstack_children : MutableMapping [str , Set [str ]] = {}
88
88
self .trunk = self ._get_trunk ()
89
+ self .original_branch = git_get_current_branch ()
89
90
for branch , parent in self .gitstack .items ():
90
91
self .gitstack_children .setdefault (parent , set ()).add (branch )
91
92
@@ -96,7 +97,7 @@ def operate(self, operation: str, args: List[str]) -> None:
96
97
branch = args [0 ]
97
98
parent : str
98
99
if len (args ) > 1 :
99
- parent = git_get_current_branch () if args [1 ] == "." else args [1 ]
100
+ parent = self . original_branch if args [1 ] == "." else args [1 ]
100
101
else :
101
102
parent = self .trunk
102
103
self .create_branch (branch , parent )
@@ -113,6 +114,9 @@ def operate(self, operation: str, args: List[str]) -> None:
113
114
assert len (args ) == 1
114
115
parent = args [0 ]
115
116
self .track_current_branch (parent )
117
+ elif operation in {"su" , "submit" }:
118
+ assert len (args ) == 0
119
+ self .submit_stack ()
116
120
elif operation in {"s" , "sync" }:
117
121
assert len (args ) == 0
118
122
self .sync ()
@@ -124,11 +128,42 @@ def wrapup(self) -> None:
124
128
125
129
def print_stack (self ):
126
130
"""Pretty print the entire stack"""
127
- current_branch = git_get_current_branch ()
128
131
self ._traverse_stack (
129
- lambda branch , depth : print_branch_level (branch , current_branch , depth )
132
+ lambda branch , depth : print_branch_level (
133
+ branch , self .original_branch , depth
134
+ )
130
135
)
131
136
137
+ def submit_stack (self ):
138
+ """Submit the stack starting at the current branch going down"""
139
+ while branch != self .trunk :
140
+ p = subprocess .run (
141
+ [
142
+ "gh" ,
143
+ "pr" ,
144
+ "status" ,
145
+ "--json" ,
146
+ "state" ,
147
+ "--jq" ,
148
+ ".currentBranch" ,
149
+ ],
150
+ check = True ,
151
+ capture_output = True ,
152
+ )
153
+ has_pr = bool (p .stdout .decode ().strip ())
154
+ if has_pr :
155
+ pass
156
+ else :
157
+ parent = self .gitstack [branch ]
158
+ subprocess .run (
159
+ ["gh" , "pr" , "create" , "--base" , parent ],
160
+ check = True ,
161
+ stdout = sys .stdout .buffer ,
162
+ stderr = sys .stderr .buffer ,
163
+ )
164
+
165
+ branch = self .switch_to_parent ()
166
+
132
167
def create_branch (self , branch : str , parent ) -> None :
133
168
"""Create new branch and add to gitstack"""
134
169
subprocess .run (
@@ -166,36 +201,37 @@ def track_current_branch(self, parent):
166
201
167
202
self ._track_branch (branch , parent )
168
203
169
- def switch_to_parent (self ) -> None :
204
+ def switch_to_parent (self ) -> str :
170
205
"""Go one step above the stack, closer to trunk"""
171
206
current_branch = git_get_current_branch ()
172
207
if current_branch == self .trunk :
173
208
print ("Already on trunk" )
174
- return
209
+ return current_branch
175
210
if current_branch not in self .gitstack :
176
211
print (
177
212
f"Current branch { current_branch } not tracked by gst, use `gst t <parent>` and try again"
178
213
)
179
- return
180
- parent = self .gitstack [git_get_current_branch () ]
214
+ return current_branch
215
+ parent = self .gitstack [current_branch ]
181
216
subprocess .run (
182
217
["git" , "switch" , parent ],
183
218
check = True ,
184
219
stdout = sys .stdout .buffer ,
185
220
stderr = sys .stderr .buffer ,
186
221
)
222
+ return parent
187
223
188
- def switch_to_child (self ) -> None :
224
+ def switch_to_child (self ) -> str :
189
225
"""Go one step deeper into the stack, further from trunk"""
190
226
current_branch = git_get_current_branch ()
191
227
if current_branch != self .trunk and current_branch not in self .gitstack :
192
228
print (f"Current branch { current_branch } isn't tracked by gst." )
193
- return
229
+ return current_branch
194
230
195
- child_branches = self .gitstack_children .get (git_get_current_branch () , set ())
231
+ child_branches = self .gitstack_children .get (current_branch , set ())
196
232
if len (child_branches ) < 1 :
197
233
print (f"Current branch { current_branch } has no children." )
198
- return
234
+ return current_branch
199
235
200
236
child_branch : str
201
237
if len (child_branches ) == 1 :
@@ -214,18 +250,20 @@ def switch_to_child(self) -> None:
214
250
stdout = sys .stdout .buffer ,
215
251
stderr = sys .stderr .buffer ,
216
252
)
253
+ return child_branch
217
254
218
255
def sync (self ):
219
256
"""Rebase all branches on top of current trunk"""
220
- current_branch = git_get_current_branch ()
221
257
self ._traverse_stack (lambda branch , depth : self ._check_and_rebase (branch ))
222
- # switch back to original branch once done
223
- subprocess .run (
224
- ["git" , "switch" , current_branch ],
225
- check = True ,
226
- stdout = sys .stdout .buffer ,
227
- stderr = sys .stderr .buffer ,
228
- )
258
+ # switch back to original branch once done, if it exists - it may have
259
+ # been deleted in the process of sync
260
+ if self .original_branch in git_list_all_branches ():
261
+ subprocess .run (
262
+ ["git" , "switch" , self .original_branch ],
263
+ check = True ,
264
+ stdout = sys .stdout .buffer ,
265
+ stderr = sys .stderr .buffer ,
266
+ )
229
267
230
268
def _traverse_stack (self , fn : Callable [[str , int ], None ]):
231
269
"""DFS through the gitstack from trunk, calling a function on each branch"""
0 commit comments