1414#include "cache.h"
1515#include "parse-options.h"
1616#include "run-command.h"
17+ #include "argv-array.h"
1718
1819#define FAILED_RUN "failed to run %s"
1920
@@ -28,12 +29,11 @@ static int gc_auto_threshold = 6700;
2829static int gc_auto_pack_limit = 50 ;
2930static const char * prune_expire = "2.weeks.ago" ;
3031
31- #define MAX_ADD 10
32- static const char * argv_pack_refs [] = {"pack-refs" , "--all" , "--prune" , NULL };
33- static const char * argv_reflog [] = {"reflog" , "expire" , "--all" , NULL };
34- static const char * argv_repack [MAX_ADD ] = {"repack" , "-d" , "-l" , NULL };
35- static const char * argv_prune [] = {"prune" , "--expire" , NULL , NULL , NULL };
36- static const char * argv_rerere [] = {"rerere" , "gc" , NULL };
32+ static struct argv_array pack_refs_cmd = ARGV_ARRAY_INIT ;
33+ static struct argv_array reflog = ARGV_ARRAY_INIT ;
34+ static struct argv_array repack = ARGV_ARRAY_INIT ;
35+ static struct argv_array prune = ARGV_ARRAY_INIT ;
36+ static struct argv_array rerere = ARGV_ARRAY_INIT ;
3737
3838static int gc_config (const char * var , const char * value , void * cb )
3939{
@@ -67,19 +67,6 @@ static int gc_config(const char *var, const char *value, void *cb)
6767 return git_default_config (var , value , cb );
6868}
6969
70- static void append_option (const char * * cmd , const char * opt , int max_length )
71- {
72- int i ;
73-
74- for (i = 0 ; cmd [i ]; i ++ )
75- ;
76-
77- if (i + 2 >= max_length )
78- die (_ ("Too many options specified" ));
79- cmd [i ++ ] = opt ;
80- cmd [i ] = NULL ;
81- }
82-
8370static int too_many_loose_objects (void )
8471{
8572 /*
@@ -144,6 +131,17 @@ static int too_many_packs(void)
144131 return gc_auto_pack_limit <= cnt ;
145132}
146133
134+ static void add_repack_all_option (void )
135+ {
136+ if (prune_expire && !strcmp (prune_expire , "now" ))
137+ argv_array_push (& repack , "-a" );
138+ else {
139+ argv_array_push (& repack , "-A" );
140+ if (prune_expire )
141+ argv_array_pushf (& repack , "--unpack-unreachable=%s" , prune_expire );
142+ }
143+ }
144+
147145static int need_to_gc (void )
148146{
149147 /*
@@ -160,10 +158,7 @@ static int need_to_gc(void)
160158 * there is no need.
161159 */
162160 if (too_many_packs ())
163- append_option (argv_repack ,
164- prune_expire && !strcmp (prune_expire , "now" ) ?
165- "-a" : "-A" ,
166- MAX_ADD );
161+ add_repack_all_option ();
167162 else if (!too_many_loose_objects ())
168163 return 0 ;
169164
@@ -177,7 +172,6 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
177172 int aggressive = 0 ;
178173 int auto_gc = 0 ;
179174 int quiet = 0 ;
180- char buf [80 ];
181175
182176 struct option builtin_gc_options [] = {
183177 OPT__QUIET (& quiet , "suppress progress reporting" ),
@@ -192,6 +186,12 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
192186 if (argc == 2 && !strcmp (argv [1 ], "-h" ))
193187 usage_with_options (builtin_gc_usage , builtin_gc_options );
194188
189+ argv_array_pushl (& pack_refs_cmd , "pack-refs" , "--all" , "--prune" , NULL );
190+ argv_array_pushl (& reflog , "reflog" , "expire" , "--all" , NULL );
191+ argv_array_pushl (& repack , "repack" , "-d" , "-l" , NULL );
192+ argv_array_pushl (& prune , "prune" , "--expire" , NULL );
193+ argv_array_pushl (& rerere , "rerere" , "gc" , NULL );
194+
195195 git_config (gc_config , NULL );
196196
197197 if (pack_refs < 0 )
@@ -203,15 +203,13 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
203203 usage_with_options (builtin_gc_usage , builtin_gc_options );
204204
205205 if (aggressive ) {
206- append_option (argv_repack , "-f" , MAX_ADD );
207- append_option (argv_repack , "--depth=250" , MAX_ADD );
208- if (aggressive_window > 0 ) {
209- sprintf (buf , "--window=%d" , aggressive_window );
210- append_option (argv_repack , buf , MAX_ADD );
211- }
206+ argv_array_push (& repack , "-f" );
207+ argv_array_push (& repack , "--depth=250" );
208+ if (aggressive_window > 0 )
209+ argv_array_pushf (& repack , "--window=%d" , aggressive_window );
212210 }
213211 if (quiet )
214- append_option ( argv_repack , "-q" , MAX_ADD );
212+ argv_array_push ( & repack , "-q" );
215213
216214 if (auto_gc ) {
217215 /*
@@ -227,30 +225,27 @@ int cmd_gc(int argc, const char **argv, const char *prefix)
227225 "run \"git gc\" manually. See "
228226 "\"git help gc\" for more information.\n" ));
229227 } else
230- append_option (argv_repack ,
231- prune_expire && !strcmp (prune_expire , "now" )
232- ? "-a" : "-A" ,
233- MAX_ADD );
228+ add_repack_all_option ();
234229
235- if (pack_refs && run_command_v_opt (argv_pack_refs , RUN_GIT_CMD ))
236- return error (FAILED_RUN , argv_pack_refs [0 ]);
230+ if (pack_refs && run_command_v_opt (pack_refs_cmd . argv , RUN_GIT_CMD ))
231+ return error (FAILED_RUN , pack_refs_cmd . argv [0 ]);
237232
238- if (run_command_v_opt (argv_reflog , RUN_GIT_CMD ))
239- return error (FAILED_RUN , argv_reflog [0 ]);
233+ if (run_command_v_opt (reflog . argv , RUN_GIT_CMD ))
234+ return error (FAILED_RUN , reflog . argv [0 ]);
240235
241- if (run_command_v_opt (argv_repack , RUN_GIT_CMD ))
242- return error (FAILED_RUN , argv_repack [0 ]);
236+ if (run_command_v_opt (repack . argv , RUN_GIT_CMD ))
237+ return error (FAILED_RUN , repack . argv [0 ]);
243238
244239 if (prune_expire ) {
245- argv_prune [ 2 ] = prune_expire ;
240+ argv_array_push ( & prune , prune_expire ) ;
246241 if (quiet )
247- argv_prune [ 3 ] = "--no-progress" ;
248- if (run_command_v_opt (argv_prune , RUN_GIT_CMD ))
249- return error (FAILED_RUN , argv_prune [0 ]);
242+ argv_array_push ( & prune , "--no-progress" ) ;
243+ if (run_command_v_opt (prune . argv , RUN_GIT_CMD ))
244+ return error (FAILED_RUN , prune . argv [0 ]);
250245 }
251246
252- if (run_command_v_opt (argv_rerere , RUN_GIT_CMD ))
253- return error (FAILED_RUN , argv_rerere [0 ]);
247+ if (run_command_v_opt (rerere . argv , RUN_GIT_CMD ))
248+ return error (FAILED_RUN , rerere . argv [0 ]);
254249
255250 if (auto_gc && too_many_loose_objects ())
256251 warning (_ ("There are too many unreachable loose objects; "
0 commit comments