17
17
#include "hex.h"
18
18
#include "repository.h"
19
19
#include "config.h"
20
+ #include "string-list.h"
20
21
#include "tempfile.h"
21
22
#include "lockfile.h"
22
23
#include "parse-options.h"
@@ -246,6 +247,7 @@ struct maintenance_run_opts {
246
247
int quiet ;
247
248
enum schedule_priority schedule ;
248
249
};
250
+
249
251
#define MAINTENANCE_RUN_OPTS_INIT { \
250
252
.detach = -1, \
251
253
}
@@ -880,6 +882,22 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
880
882
return 0 ;
881
883
}
882
884
885
+ struct maintenance_config {
886
+ struct prefetch_config_list {
887
+ struct prefetch_config {
888
+ char * remote ;
889
+ struct string_list refs ;
890
+ } * items ;
891
+ int nr , alloc ;
892
+ } prefetch ;
893
+ };
894
+
895
+ #define MAINTENANCE_CONFIG_INIT { \
896
+ .prefetch = { NULL, 0, 0 }, \
897
+ }
898
+
899
+ static struct maintenance_config maintenance_cfg = MAINTENANCE_CONFIG_INIT ;
900
+
883
901
static const char * const builtin_maintenance_run_usage [] = {
884
902
N_ ("git maintenance run [--auto] [--[no-]quiet] [--task=<task>] [--schedule]" ),
885
903
NULL
@@ -1023,22 +1041,94 @@ static int fetch_remote(struct remote *remote, void *cbdata)
1023
1041
{
1024
1042
struct maintenance_run_opts * opts = cbdata ;
1025
1043
struct child_process child = CHILD_PROCESS_INIT ;
1044
+ struct prefetch_config * prefetch_cfg = NULL ;
1045
+ static int has_prefetch_cfg = -1 ; // -1: unknown, 0: no config, 1: config exists
1026
1046
1027
1047
if (remote -> skip_default_update )
1028
1048
return 0 ;
1029
1049
1050
+ if (has_prefetch_cfg == -1 )
1051
+ has_prefetch_cfg = (maintenance_cfg .prefetch .nr > 0 );
1052
+
1053
+ if (has_prefetch_cfg ) {
1054
+ for (int i = 0 ; i < maintenance_cfg .prefetch .nr ; i ++ ) {
1055
+ if (!strcmp (remote -> name , maintenance_cfg .prefetch .items [i ].remote )) {
1056
+ prefetch_cfg = & maintenance_cfg .prefetch .items [i ];
1057
+ break ;
1058
+ }
1059
+ }
1060
+
1061
+ if (!prefetch_cfg )
1062
+ return 0 ;
1063
+ }
1064
+
1030
1065
child .git_cmd = 1 ;
1031
- strvec_pushl (& child .args , "fetch" , remote -> name ,
1032
- "--prefetch" , "--prune" , "--no-tags" ,
1033
- "--no-write-fetch-head" , "--recurse-submodules=no" ,
1034
- NULL );
1066
+ strvec_pushl (& child .args , "fetch" , remote -> name , "--prefetch" , "--prune" , "--no-tags" ,
1067
+ "--no-write-fetch-head" , "--recurse-submodules=no" , NULL );
1035
1068
1036
1069
if (opts -> quiet )
1037
1070
strvec_push (& child .args , "--quiet" );
1038
1071
1072
+ if (prefetch_cfg && prefetch_cfg -> refs .nr > 0 ) {
1073
+ struct string_list_item * item ;
1074
+ for_each_string_list_item (item , & prefetch_cfg -> refs )
1075
+ strvec_pushf (& child .args , "%s:%s" , item -> string , item -> string );
1076
+ }
1077
+
1039
1078
return !!run_command (& child );
1040
1079
}
1041
1080
1081
+ static int maintenance_config_callback (const char * key , const char * value ,
1082
+ const struct config_context * ctx ,
1083
+ void * data )
1084
+ {
1085
+ struct maintenance_config * config = data ;
1086
+ const char * remote_name ;
1087
+ const char * refs_key ;
1088
+ struct prefetch_config * pc ;
1089
+ struct strbuf name = STRBUF_INIT ;
1090
+
1091
+ if (!skip_prefix (key , "maintenance.prefetch." , & remote_name ))
1092
+ return 0 ;
1093
+
1094
+ refs_key = strrchr (remote_name , '.' );
1095
+ if (!refs_key || strcmp (refs_key + 1 , "refs" ))
1096
+ return 0 ;
1097
+
1098
+ strbuf_add (& name , remote_name , refs_key - remote_name );
1099
+
1100
+ REALLOC_ARRAY (config -> prefetch .items , config -> prefetch .nr + 1 );
1101
+ pc = & config -> prefetch .items [config -> prefetch .nr ++ ];
1102
+ pc -> remote = strbuf_detach (& name , NULL );
1103
+ string_list_init_dup (& pc -> refs );
1104
+ pc -> refs .strdup_strings = 1 ;
1105
+ string_list_split (& pc -> refs , value , ' ' , -1 );
1106
+
1107
+ return 0 ;
1108
+ }
1109
+
1110
+ static void maintenance_config_read (struct maintenance_config * config )
1111
+ {
1112
+ if (git_config (maintenance_config_callback , config ) < 0 )
1113
+ die (_ ("failed to read maintenance configuration" ));
1114
+ }
1115
+
1116
+ static void maintenance_config_release (struct maintenance_config * config )
1117
+ {
1118
+ int i ;
1119
+
1120
+ if (!config -> prefetch .items )
1121
+ return ;
1122
+
1123
+ for (i = 0 ; i < config -> prefetch .nr ; i ++ ) {
1124
+ free (config -> prefetch .items [i ].remote );
1125
+ string_list_clear (& config -> prefetch .items [i ].refs , 1 );
1126
+ }
1127
+
1128
+ free (config -> prefetch .items );
1129
+ memset (config , 0 , sizeof (* config ));
1130
+ }
1131
+
1042
1132
static int maintenance_task_prefetch (struct maintenance_run_opts * opts ,
1043
1133
struct gc_config * cfg )
1044
1134
{
@@ -1563,7 +1653,7 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
1563
1653
{
1564
1654
int i ;
1565
1655
struct maintenance_run_opts opts = MAINTENANCE_RUN_OPTS_INIT ;
1566
- struct gc_config cfg = GC_CONFIG_INIT ;
1656
+ struct gc_config gc_cfg = GC_CONFIG_INIT ;
1567
1657
struct option builtin_maintenance_run_options [] = {
1568
1658
OPT_BOOL (0 , "auto" , & opts .auto_flag ,
1569
1659
N_ ("run tasks based on the state of the repository" )),
@@ -1579,8 +1669,11 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
1579
1669
PARSE_OPT_NONEG , task_option_parse ),
1580
1670
OPT_END ()
1581
1671
};
1672
+
1582
1673
int ret ;
1583
1674
1675
+ maintenance_config_read (& maintenance_cfg );
1676
+
1584
1677
opts .quiet = !isatty (2 );
1585
1678
1586
1679
for (i = 0 ; i < TASK__COUNT ; i ++ )
@@ -1591,18 +1684,22 @@ static int maintenance_run(int argc, const char **argv, const char *prefix)
1591
1684
builtin_maintenance_run_usage ,
1592
1685
PARSE_OPT_STOP_AT_NON_OPTION );
1593
1686
1687
+
1688
+ maintenance_config_read (& maintenance_cfg );
1689
+
1594
1690
if (opts .auto_flag && opts .schedule )
1595
1691
die (_ ("use at most one of --auto and --schedule=<frequency>" ));
1596
1692
1597
- gc_config (& cfg );
1693
+ gc_config (& gc_cfg );
1598
1694
initialize_task_config (opts .schedule );
1599
1695
1600
1696
if (argc != 0 )
1601
1697
usage_with_options (builtin_maintenance_run_usage ,
1602
1698
builtin_maintenance_run_options );
1603
1699
1604
- ret = maintenance_run_tasks (& opts , & cfg );
1605
- gc_config_release (& cfg );
1700
+ ret = maintenance_run_tasks (& opts , & gc_cfg );
1701
+ gc_config_release (& gc_cfg );
1702
+ maintenance_config_release (& maintenance_cfg );
1606
1703
return ret ;
1607
1704
}
1608
1705
0 commit comments