@@ -141,18 +141,34 @@ pub struct SubmitOptions {
141
141
142
142
/// The result of creating a commit.
143
143
#[ derive( Clone , Debug ) ]
144
- pub struct CreateStatus {
145
- /// The commit OID after carrying out the creation process. Usually, this
146
- /// will be the same as the original commit OID, unless the forge amends it
147
- /// (e.g. to include a change ID).
148
- pub final_commit_oid : NonZeroOid ,
149
-
150
- /// An identifier corresponding to the commit, for display purposes only.
151
- /// This may be a branch name, a change ID, the commit summary, etc.
152
- ///
153
- /// This does not necessarily correspond to the commit's name/identifier in
154
- /// the forge (e.g. not a code review link).
155
- pub local_commit_name : String ,
144
+ pub enum CreateStatus {
145
+ /// The commit was successfully created.
146
+ Created {
147
+ /// The commit OID after carrying out the creation process. Usually, this
148
+ /// will be the same as the original commit OID, unless the forge amends it
149
+ /// (e.g. to include a change ID).
150
+ final_commit_oid : NonZeroOid ,
151
+
152
+ /// An identifier corresponding to the commit, for display purposes only.
153
+ /// This may be a branch name, a change ID, the commit summary, etc.
154
+ ///
155
+ /// This does not necessarily correspond to the commit's name/identifier in
156
+ /// the forge (e.g. not a code review link).
157
+ local_commit_name : String ,
158
+ } ,
159
+
160
+ /// The commit was skipped. This could happen if a previous commit could not
161
+ /// be created due to an error.
162
+ Skipped {
163
+ /// The commit which was skipped.
164
+ commit_oid : NonZeroOid ,
165
+ } ,
166
+
167
+ /// The commit could not be created due to an error.
168
+ Err {
169
+ /// The commit which produced an error.
170
+ commit_oid : NonZeroOid ,
171
+ } ,
156
172
}
157
173
158
174
/// "Forge" refers to a Git hosting provider, such as GitHub, GitLab, etc.
@@ -367,30 +383,49 @@ fn submit(
367
383
( local, unsubmitted, to_update, to_skip)
368
384
} ) ;
369
385
370
- let ( submitted_commit_names, unsubmitted_commit_names) : ( BTreeSet < String > , BTreeSet < String > ) = {
386
+ let ( submitted_commit_names, unsubmitted_commit_names, create_error_commits) : (
387
+ BTreeSet < String > ,
388
+ BTreeSet < String > ,
389
+ BTreeSet < NonZeroOid > ,
390
+ ) = {
371
391
let unsubmitted_commit_names: BTreeSet < String > = unsubmitted_commits
372
392
. values ( )
373
393
. flat_map ( |commit_status| commit_status. local_commit_name . clone ( ) )
374
394
. collect ( ) ;
375
395
if create {
376
- let created_commit_names = if dry_run {
377
- unsubmitted_commit_names. clone ( )
396
+ let ( created_commit_names, error_commits ) = if dry_run {
397
+ ( unsubmitted_commit_names. clone ( ) , Default :: default ( ) )
378
398
} else {
379
399
let create_statuses =
380
400
try_exit_code ! ( forge. create( unsubmitted_commits, & submit_options) ?) ;
381
- create_statuses
382
- . into_values ( )
383
- . map (
384
- |CreateStatus {
385
- final_commit_oid : _,
386
- local_commit_name,
387
- } | local_commit_name,
388
- )
389
- . collect ( )
401
+ let mut created_commit_names = BTreeSet :: new ( ) ;
402
+ let mut error_commits = BTreeSet :: new ( ) ;
403
+ for ( _commit_oid, create_status) in create_statuses {
404
+ match create_status {
405
+ CreateStatus :: Created {
406
+ final_commit_oid : _,
407
+ local_commit_name,
408
+ } => {
409
+ created_commit_names. insert ( local_commit_name) ;
410
+ }
411
+ // For now, treat `Skipped` the same as `Err` as it would be
412
+ // a lot of work to render it differently in the output, and
413
+ // we may want to rethink the data structures before doing
414
+ // that.
415
+ CreateStatus :: Skipped { commit_oid } | CreateStatus :: Err { commit_oid } => {
416
+ error_commits. insert ( commit_oid) ;
417
+ }
418
+ }
419
+ }
420
+ ( created_commit_names, error_commits)
390
421
} ;
391
- ( created_commit_names, Default :: default ( ) )
422
+ ( created_commit_names, Default :: default ( ) , error_commits )
392
423
} else {
393
- ( Default :: default ( ) , unsubmitted_commit_names)
424
+ (
425
+ Default :: default ( ) ,
426
+ unsubmitted_commit_names,
427
+ Default :: default ( ) ,
428
+ )
394
429
}
395
430
} ;
396
431
@@ -510,8 +545,30 @@ repository. To submit them, retry this operation with the --create option.",
510
545
if dry_run { "are" } else { "were" } ,
511
546
) ?;
512
547
}
513
-
514
- Ok ( Ok ( ( ) ) )
548
+ if !create_error_commits. is_empty ( ) {
549
+ writeln ! (
550
+ effects. get_output_stream( ) ,
551
+ "Failed to create {}:" ,
552
+ Pluralize {
553
+ determiner: None ,
554
+ amount: create_error_commits. len( ) ,
555
+ unit: ( "commit" , "commits" )
556
+ } ,
557
+ ) ?;
558
+ for error_commit_oid in & create_error_commits {
559
+ let error_commit = repo. find_commit_or_fail ( * error_commit_oid) ?;
560
+ writeln ! (
561
+ effects. get_output_stream( ) ,
562
+ "{}" ,
563
+ effects
564
+ . get_glyphs( )
565
+ . render( error_commit. friendly_describe( effects. get_glyphs( ) ) ?) ?
566
+ ) ?;
567
+ }
568
+ Ok ( Err ( ExitCode ( 1 ) ) )
569
+ } else {
570
+ Ok ( Ok ( ( ) ) )
571
+ }
515
572
}
516
573
517
574
#[ instrument]
0 commit comments