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"
@@ -916,6 +917,63 @@ static int maintenance_opt_schedule(const struct option *opt, const char *arg,
916917 return 0 ;
917918}
918919
920+ struct remote_cb_data {
921+ struct maintenance_run_opts * maintenance_opts ;
922+ struct string_list failed_remotes ;
923+ };
924+
925+ static void report_failed_remotes (struct string_list * failed_remotes ,
926+ const char * action_name )
927+ {
928+ if (failed_remotes -> nr ) {
929+ int i ;
930+ struct strbuf msg = STRBUF_INIT ;
931+ strbuf_addf (& msg , _ ("failed to %s the following remotes: " ),
932+ action_name );
933+ for (i = 0 ; i < failed_remotes -> nr ; i ++ ) {
934+ if (i )
935+ strbuf_addstr (& msg , ", " );
936+ strbuf_addstr (& msg , failed_remotes -> items [i ].string );
937+ }
938+ error ("%s" , msg .buf );
939+ strbuf_release (& msg );
940+ }
941+ }
942+
943+ static int prune_remote (struct remote * remote , void * cb_data )
944+ {
945+ struct child_process child = CHILD_PROCESS_INIT ;
946+ struct remote_cb_data * data = cb_data ;
947+
948+ if (!remote -> url .nr )
949+ return 0 ;
950+
951+ child .git_cmd = 1 ;
952+ strvec_pushl (& child .args , "remote" , "prune" , remote -> name , NULL );
953+
954+ if (run_command (& child ))
955+ string_list_append (& data -> failed_remotes , remote -> name );
956+
957+ return 0 ;
958+ }
959+
960+ static int maintenance_task_prune_remote (struct maintenance_run_opts * opts ,
961+ struct gc_config * cfg UNUSED )
962+ {
963+ struct remote_cb_data cbdata = { .maintenance_opts = opts ,
964+ .failed_remotes = STRING_LIST_INIT_DUP };
965+
966+ int result ;
967+ result = for_each_remote (prune_remote , & cbdata );
968+
969+ report_failed_remotes (& cbdata .failed_remotes , "prune" );
970+ if (cbdata .failed_remotes .nr )
971+ result = 1 ;
972+
973+ string_list_clear (& cbdata .failed_remotes , 0 );
974+ return result ;
975+ }
976+
919977/* Remember to update object flag allocation in object.h */
920978#define SEEN (1u<<0)
921979
@@ -1036,8 +1094,8 @@ static int maintenance_task_commit_graph(struct maintenance_run_opts *opts,
10361094
10371095static int fetch_remote (struct remote * remote , void * cbdata )
10381096{
1039- struct maintenance_run_opts * opts = cbdata ;
10401097 struct child_process child = CHILD_PROCESS_INIT ;
1098+ struct remote_cb_data * data = cbdata ;
10411099
10421100 if (remote -> skip_default_update )
10431101 return 0 ;
@@ -1048,21 +1106,34 @@ static int fetch_remote(struct remote *remote, void *cbdata)
10481106 "--no-write-fetch-head" , "--recurse-submodules=no" ,
10491107 NULL );
10501108
1051- if (opts -> quiet )
1109+ if (data -> maintenance_opts -> quiet )
10521110 strvec_push (& child .args , "--quiet" );
10531111
1054- return !!run_command (& child );
1112+ if (run_command (& child ))
1113+ string_list_append (& data -> failed_remotes , remote -> name );
1114+
1115+ return 0 ;
10551116}
10561117
10571118static int maintenance_task_prefetch (struct maintenance_run_opts * opts ,
10581119 struct gc_config * cfg UNUSED )
10591120{
1060- if (for_each_remote (fetch_remote , opts )) {
1061- error (_ ("failed to prefetch remotes" ));
1062- return 1 ;
1121+ struct remote_cb_data cbdata = { .maintenance_opts = opts ,
1122+ .failed_remotes = STRING_LIST_INIT_DUP };
1123+
1124+ int result = 0 ;
1125+
1126+ if (for_each_remote (fetch_remote , & cbdata )) {
1127+ error (_ ("failed to prefetch some remotes" ));
1128+ result = 1 ;
10631129 }
10641130
1065- return 0 ;
1131+ report_failed_remotes (& cbdata .failed_remotes , "prefetch" );
1132+ if (cbdata .failed_remotes .nr )
1133+ result = 1 ;
1134+
1135+ string_list_clear (& cbdata .failed_remotes , 0 );
1136+ return result ;
10661137}
10671138
10681139static int maintenance_task_gc (struct maintenance_run_opts * opts ,
@@ -1378,6 +1449,7 @@ enum maintenance_task_label {
13781449 TASK_GC ,
13791450 TASK_COMMIT_GRAPH ,
13801451 TASK_PACK_REFS ,
1452+ TASK_PRUNE_REMOTE_REFS ,
13811453
13821454 /* Leave as final value */
13831455 TASK__COUNT
@@ -1414,6 +1486,10 @@ static struct maintenance_task tasks[] = {
14141486 maintenance_task_pack_refs ,
14151487 pack_refs_condition ,
14161488 },
1489+ [TASK_PRUNE_REMOTE_REFS ] = {
1490+ "prune-remote-refs" ,
1491+ maintenance_task_prune_remote ,
1492+ },
14171493};
14181494
14191495static int compare_tasks_by_selection (const void * a_ , const void * b_ )
@@ -1508,6 +1584,8 @@ static void initialize_maintenance_strategy(void)
15081584 tasks [TASK_LOOSE_OBJECTS ].schedule = SCHEDULE_DAILY ;
15091585 tasks [TASK_PACK_REFS ].enabled = 1 ;
15101586 tasks [TASK_PACK_REFS ].schedule = SCHEDULE_WEEKLY ;
1587+ tasks [TASK_PRUNE_REMOTE_REFS ].enabled = 0 ;
1588+ tasks [TASK_PRUNE_REMOTE_REFS ].schedule = SCHEDULE_DAILY ;
15111589 }
15121590}
15131591
0 commit comments