@@ -333,21 +333,17 @@ static int handle_ref_update(struct ref_transaction *transaction,
333333 NULL , NULL , 0 , reflog_msg , err );
334334}
335335
336- static int handle_reference_updates (struct rev_info * revs ,
337- enum ref_action action ,
338- struct commit * original ,
339- struct commit * rewritten ,
340- const char * reflog_msg ,
341- int dry_run ,
342- enum replay_empty_commit_action empty )
336+ static int compute_pending_ref_updates (struct rev_info * revs ,
337+ enum ref_action action ,
338+ struct commit * original ,
339+ struct commit * rewritten ,
340+ enum replay_empty_commit_action empty ,
341+ struct replay_result * result )
343342{
344343 const struct name_decoration * decoration ;
345344 struct replay_revisions_options opts = {
346345 .empty = empty ,
347346 };
348- struct replay_result result = { 0 };
349- struct ref_transaction * transaction = NULL ;
350- struct strbuf err = STRBUF_INIT ;
351347 char hex [GIT_MAX_HEXSZ + 1 ];
352348 bool detached_head ;
353349 int head_flags = 0 ;
@@ -359,34 +355,13 @@ static int handle_reference_updates(struct rev_info *revs,
359355
360356 opts .onto = oid_to_hex_r (hex , & rewritten -> object .oid );
361357
362- ret = replay_revisions (revs , & opts , & result );
358+ ret = replay_revisions (revs , & opts , result );
363359 if (ret )
364- goto out ;
360+ return ret ;
365361
366362 if (action != REF_ACTION_BRANCHES && action != REF_ACTION_HEAD )
367363 BUG ("unsupported ref action %d" , action );
368364
369- if (!dry_run ) {
370- transaction = ref_store_transaction_begin (get_main_ref_store (revs -> repo ), 0 , & err );
371- if (!transaction ) {
372- ret = error (_ ("failed to begin ref transaction: %s" ), err .buf );
373- goto out ;
374- }
375- }
376-
377- for (size_t i = 0 ; i < result .updates_nr ; i ++ ) {
378- ret = handle_ref_update (transaction ,
379- result .updates [i ].refname ,
380- & result .updates [i ].new_oid ,
381- & result .updates [i ].old_oid ,
382- reflog_msg , & err );
383- if (ret ) {
384- ret = error (_ ("failed to update ref '%s': %s" ),
385- result .updates [i ].refname , err .buf );
386- goto out ;
387- }
388- }
389-
390365 /*
391366 * `replay_revisions()` only updates references that are
392367 * ancestors of `rewritten`, so we need to manually
@@ -414,14 +389,43 @@ static int handle_reference_updates(struct rev_info *revs,
414389 !detached_head )
415390 continue ;
416391
392+ ALLOC_GROW (result -> updates , result -> updates_nr + 1 , result -> updates_alloc );
393+ result -> updates [result -> updates_nr ].refname = xstrdup (decoration -> name );
394+ result -> updates [result -> updates_nr ].old_oid = original -> object .oid ;
395+ result -> updates [result -> updates_nr ].new_oid = rewritten -> object .oid ;
396+ result -> updates_nr ++ ;
397+ }
398+
399+ return 0 ;
400+ }
401+
402+ static int apply_pending_ref_updates (struct repository * repo ,
403+ const struct replay_result * result ,
404+ const char * reflog_msg ,
405+ int dry_run )
406+ {
407+ struct ref_transaction * transaction = NULL ;
408+ struct strbuf err = STRBUF_INIT ;
409+ int ret ;
410+
411+ if (!dry_run ) {
412+ transaction = ref_store_transaction_begin (get_main_ref_store (repo ),
413+ 0 , & err );
414+ if (!transaction ) {
415+ ret = error (_ ("failed to begin ref transaction: %s" ), err .buf );
416+ goto out ;
417+ }
418+ }
419+
420+ for (size_t i = 0 ; i < result -> updates_nr ; i ++ ) {
417421 ret = handle_ref_update (transaction ,
418- decoration -> name ,
419- & rewritten -> object . oid ,
420- & original -> object . oid ,
422+ result -> updates [ i ]. refname ,
423+ & result -> updates [ i ]. new_oid ,
424+ & result -> updates [ i ]. old_oid ,
421425 reflog_msg , & err );
422426 if (ret ) {
423427 ret = error (_ ("failed to update ref '%s': %s" ),
424- decoration -> name , err .buf );
428+ result -> updates [ i ]. refname , err .buf );
425429 goto out ;
426430 }
427431 }
@@ -435,11 +439,33 @@ static int handle_reference_updates(struct rev_info *revs,
435439
436440out :
437441 ref_transaction_free (transaction );
438- replay_result_release (& result );
439442 strbuf_release (& err );
440443 return ret ;
441444}
442445
446+ static int handle_reference_updates (struct rev_info * revs ,
447+ enum ref_action action ,
448+ struct commit * original ,
449+ struct commit * rewritten ,
450+ const char * reflog_msg ,
451+ int dry_run ,
452+ enum replay_empty_commit_action empty )
453+ {
454+ struct replay_result result = { 0 };
455+ int ret ;
456+
457+ ret = compute_pending_ref_updates (revs , action , original , rewritten ,
458+ empty , & result );
459+ if (ret )
460+ goto out ;
461+
462+ ret = apply_pending_ref_updates (revs -> repo , & result , reflog_msg , dry_run );
463+
464+ out :
465+ replay_result_release (& result );
466+ return ret ;
467+ }
468+
443469static int commit_became_empty (struct repository * repo ,
444470 struct commit * original ,
445471 struct tree * result )
0 commit comments