@@ -130,54 +130,135 @@ pub async fn run(yes: bool) -> anyhow::Result<()> {
130
130
& info. remote . local_remote_alias ,
131
131
) ?;
132
132
133
- if config. pull_requests . is_empty ( ) {
133
+ let has_pull_requests = !config. pull_requests . is_empty ( ) ;
134
+ let has_branches = !config. branches . is_empty ( ) ;
135
+
136
+ if !has_pull_requests && !has_branches {
134
137
log:: info!(
135
- "You haven't specified any pull requests to fetch in your config, {}" ,
138
+ "You haven't specified any pull requests or branches to fetch in your config, {}" ,
136
139
display_link(
137
140
"see the instructions on how to configure patchy." ,
138
141
"https://github.com/nik-rev/patchy?tab=readme-ov-file#config"
139
142
)
140
143
) ;
141
144
} else {
142
- // TODO: make this concurrent, see https://users.rust-lang.org/t/processing-subprocesses-concurrently/79638/3
143
- // Git cannot handle multiple threads executing commands in the same repository,
144
- // so we can't use threads, but we can run processes in the background
145
- for pull_request in & config. pull_requests {
146
- let pull_request = ignore_octothorpe ( pull_request) ;
147
- let ( pull_request, commit_hash) = parse_if_maybe_hash ( & pull_request, " @ " ) ;
148
- // TODO: refactor this to not use such deep nesting
149
- match git:: fetch_pull_request ( & config. repo , & pull_request, None , commit_hash. as_ref ( ) )
145
+ // Process pull requests
146
+ if has_pull_requests {
147
+ // TODO: make this concurrent, see https://users.rust-lang.org/t/processing-subprocesses-concurrently/79638/3
148
+ // Git cannot handle multiple threads executing commands in the same repository,
149
+ // so we can't use threads, but we can run processes in the background
150
+ for pull_request in & config. pull_requests {
151
+ let pull_request = ignore_octothorpe ( pull_request) ;
152
+ let ( pull_request, commit_hash) = parse_if_maybe_hash ( & pull_request, " @ " ) ;
153
+ // TODO: refactor this to not use such deep nesting
154
+ match git:: fetch_pull_request (
155
+ & config. repo ,
156
+ & pull_request,
157
+ None ,
158
+ commit_hash. as_ref ( ) ,
159
+ )
150
160
. await
151
- {
152
- Ok ( ( response, info) ) => {
153
- match git:: merge_pull_request (
154
- & info,
155
- & pull_request,
156
- & response. title ,
157
- & response. html_url ,
158
- ) {
159
- Ok ( ( ) ) => {
160
- success ! (
161
- "Merged pull request {}" ,
162
- display_link(
163
- & format!(
164
- "{}{}{}{}" ,
165
- "#" . bright_blue( ) ,
166
- pull_request. bright_blue( ) ,
167
- " " . bright_blue( ) ,
168
- & response. title. bright_blue( ) . italic( )
161
+ {
162
+ Ok ( ( response, info) ) => {
163
+ match git:: merge_pull_request (
164
+ & info,
165
+ & pull_request,
166
+ & response. title ,
167
+ & response. html_url ,
168
+ ) {
169
+ Ok ( ( ) ) => {
170
+ success ! (
171
+ "Merged pull request {}" ,
172
+ display_link(
173
+ & format!(
174
+ "{}{}{}{}" ,
175
+ "#" . bright_blue( ) ,
176
+ pull_request. bright_blue( ) ,
177
+ " " . bright_blue( ) ,
178
+ & response. title. bright_blue( ) . italic( )
179
+ ) ,
180
+ & response. html_url
169
181
) ,
170
- & response. html_url
171
- ) ,
172
- ) ;
173
- }
174
- Err ( err) => {
175
- fail ! ( "{err}" ) ;
182
+ ) ;
183
+ }
184
+ Err ( err) => {
185
+ fail ! ( "{err}" ) ;
186
+ }
176
187
}
177
188
}
189
+ Err ( err) => {
190
+ fail ! ( "Could not fetch branch from remote\n {err}" ) ;
191
+ }
178
192
}
179
- Err ( err) => {
180
- fail ! ( "Could not fetch branch from remote\n {err}" ) ;
193
+ }
194
+ }
195
+
196
+ // Process branches
197
+ if has_branches {
198
+ for branch_entry in & config. branches {
199
+ let ( branch_path, commit_hash) = parse_if_maybe_hash ( branch_entry, " @ " ) ;
200
+
201
+ // Parse the branch path into owner/repo/branch format
202
+ let parts: Vec < & str > = branch_path. split ( '/' ) . collect ( ) ;
203
+ if parts. len ( ) < 3 {
204
+ fail ! (
205
+ "Invalid branch format: {}. Expected format: owner/repo/branch" ,
206
+ branch_path
207
+ ) ;
208
+ continue ;
209
+ }
210
+
211
+ let owner = parts[ 0 ] ;
212
+ let repo = parts[ 1 ] ;
213
+ let branch_name = parts[ 2 ..] . join ( "/" ) ;
214
+
215
+ let remote = crate :: cli:: Remote {
216
+ owner : owner. to_string ( ) ,
217
+ repo : repo. to_string ( ) ,
218
+ branch : branch_name. clone ( ) ,
219
+ } ;
220
+
221
+ match git:: fetch_branch ( & remote, commit_hash. as_ref ( ) ) . await {
222
+ Ok ( ( _, info) ) => {
223
+ match git:: merge_into_main (
224
+ & info. branch . local_branch_name ,
225
+ & info. branch . upstream_branch_name ,
226
+ ) {
227
+ Ok ( _) => {
228
+ success ! (
229
+ "Merged branch {}/{}/{} {}" ,
230
+ owner. bright_blue( ) ,
231
+ repo. bright_blue( ) ,
232
+ branch_name. bright_blue( ) ,
233
+ commit_hash
234
+ . map( |hash| format!(
235
+ "at commit {}" ,
236
+ hash. as_ref( ) . bright_yellow( )
237
+ ) )
238
+ . unwrap_or_default( )
239
+ ) ;
240
+
241
+ // Clean up the remote branch
242
+ if let Err ( err) = git:: delete_remote_and_branch (
243
+ & info. remote . local_remote_alias ,
244
+ & info. branch . local_branch_name ,
245
+ ) {
246
+ fail ! ( "Failed to clean up branch: {err}" ) ;
247
+ }
248
+ }
249
+ Err ( err) => {
250
+ fail ! ( "{err}" ) ;
251
+ }
252
+ }
253
+ }
254
+ Err ( err) => {
255
+ fail ! (
256
+ "Could not fetch branch {}/{}/{}: {err}" ,
257
+ owner,
258
+ repo,
259
+ branch_name
260
+ ) ;
261
+ }
181
262
}
182
263
}
183
264
}
0 commit comments