2323#include "lockfile.h"
2424#include "parse-options.h"
2525#include "run-command.h"
26+ #include "remote.h"
2627#include "sigchain.h"
2728#include "strvec.h"
2829#include "commit.h"
@@ -921,6 +922,63 @@ static int maintenance_opt_schedule(const struct option *opt, const char *arg,
921922 return 0 ;
922923}
923924
925+ struct remote_cb_data {
926+ struct maintenance_run_opts * maintenance_opts ;
927+ struct string_list failed_remotes ;
928+ };
929+
930+ static void report_failed_remotes (struct string_list * failed_remotes ,
931+ const char * action_name )
932+ {
933+ if (failed_remotes -> nr ) {
934+ int i ;
935+ struct strbuf msg = STRBUF_INIT ;
936+ strbuf_addf (& msg , _ ("failed to %s the following remotes: " ),
937+ action_name );
938+ for (i = 0 ; i < failed_remotes -> nr ; i ++ ) {
939+ if (i )
940+ strbuf_addstr (& msg , ", " );
941+ strbuf_addstr (& msg , failed_remotes -> items [i ].string );
942+ }
943+ error ("%s" , msg .buf );
944+ strbuf_release (& msg );
945+ }
946+ }
947+
948+ static int prune_remote (struct remote * remote , void * cb_data )
949+ {
950+ struct child_process child = CHILD_PROCESS_INIT ;
951+ struct remote_cb_data * data = cb_data ;
952+
953+ if (!remote -> url .nr )
954+ return 0 ;
955+
956+ child .git_cmd = 1 ;
957+ strvec_pushl (& child .args , "remote" , "prune" , remote -> name , NULL );
958+
959+ if (run_command (& child ))
960+ string_list_append (& data -> failed_remotes , remote -> name );
961+
962+ return 0 ;
963+ }
964+
965+ static int maintenance_task_prune_remote (struct maintenance_run_opts * opts ,
966+ struct gc_config * cfg UNUSED )
967+ {
968+ struct remote_cb_data cbdata = { .maintenance_opts = opts ,
969+ .failed_remotes = STRING_LIST_INIT_DUP };
970+
971+ int result ;
972+ result = for_each_remote (prune_remote , & cbdata );
973+
974+ report_failed_remotes (& cbdata .failed_remotes , "prune" );
975+ if (cbdata .failed_remotes .nr )
976+ result = 1 ;
977+
978+ string_list_clear (& cbdata .failed_remotes , 0 );
979+ return result ;
980+ }
981+
924982/* Remember to update object flag allocation in object.h */
925983#define SEEN (1u<<0)
926984
@@ -1041,8 +1099,8 @@ static int maintenance_task_commit_graph(struct maintenance_run_opts *opts,
10411099
10421100static int fetch_remote (struct remote * remote , void * cbdata )
10431101{
1044- struct maintenance_run_opts * opts = cbdata ;
10451102 struct child_process child = CHILD_PROCESS_INIT ;
1103+ struct remote_cb_data * data = cbdata ;
10461104
10471105 if (remote -> skip_default_update )
10481106 return 0 ;
@@ -1053,21 +1111,34 @@ static int fetch_remote(struct remote *remote, void *cbdata)
10531111 "--no-write-fetch-head" , "--recurse-submodules=no" ,
10541112 NULL );
10551113
1056- if (opts -> quiet )
1114+ if (data -> maintenance_opts -> quiet )
10571115 strvec_push (& child .args , "--quiet" );
10581116
1059- return !!run_command (& child );
1117+ if (run_command (& child ))
1118+ string_list_append (& data -> failed_remotes , remote -> name );
1119+
1120+ return 0 ;
10601121}
10611122
10621123static int maintenance_task_prefetch (struct maintenance_run_opts * opts ,
10631124 struct gc_config * cfg UNUSED )
10641125{
1065- if (for_each_remote (fetch_remote , opts )) {
1066- error (_ ("failed to prefetch remotes" ));
1067- return 1 ;
1126+ struct remote_cb_data cbdata = { .maintenance_opts = opts ,
1127+ .failed_remotes = STRING_LIST_INIT_DUP };
1128+
1129+ int result = 0 ;
1130+
1131+ if (for_each_remote (fetch_remote , & cbdata )) {
1132+ error (_ ("failed to prefetch some remotes" ));
1133+ result = 1 ;
10681134 }
10691135
1070- return 0 ;
1136+ report_failed_remotes (& cbdata .failed_remotes , "prefetch" );
1137+ if (cbdata .failed_remotes .nr )
1138+ result = 1 ;
1139+
1140+ string_list_clear (& cbdata .failed_remotes , 0 );
1141+ return result ;
10711142}
10721143
10731144static int maintenance_task_gc (struct maintenance_run_opts * opts ,
@@ -1383,6 +1454,7 @@ enum maintenance_task_label {
13831454 TASK_GC ,
13841455 TASK_COMMIT_GRAPH ,
13851456 TASK_PACK_REFS ,
1457+ TASK_PRUNE_REMOTE_REFS ,
13861458
13871459 /* Leave as final value */
13881460 TASK__COUNT
@@ -1419,6 +1491,10 @@ static struct maintenance_task tasks[] = {
14191491 maintenance_task_pack_refs ,
14201492 pack_refs_condition ,
14211493 },
1494+ [TASK_PRUNE_REMOTE_REFS ] = {
1495+ "prune-remote-refs" ,
1496+ maintenance_task_prune_remote ,
1497+ },
14221498};
14231499
14241500static int compare_tasks_by_selection (const void * a_ , const void * b_ )
@@ -1513,6 +1589,8 @@ static void initialize_maintenance_strategy(void)
15131589 tasks [TASK_LOOSE_OBJECTS ].schedule = SCHEDULE_DAILY ;
15141590 tasks [TASK_PACK_REFS ].enabled = 1 ;
15151591 tasks [TASK_PACK_REFS ].schedule = SCHEDULE_WEEKLY ;
1592+ tasks [TASK_PRUNE_REMOTE_REFS ].enabled = 0 ;
1593+ tasks [TASK_PRUNE_REMOTE_REFS ].schedule = SCHEDULE_DAILY ;
15161594 }
15171595}
15181596
0 commit comments