44#include "config.h"
55#include "environment.h"
66#include "gettext.h"
7+ #include "parse.h"
78#include "parse-options.h"
89#include "midx.h"
910#include "strbuf.h"
2223#define BUILTIN_MIDX_COMPACT_USAGE \
2324 N_("git multi-pack-index [<options>] compact [--[no-]incremental]\n" \
2425 " [--[no-]bitmap] [--base=<checksum>] [--[no-]write-chain-file]\n" \
25- " < from> <to>")
26+ " [--max-chain-depth=<n> [--split-factor=<n>]] [< from> <to>] ")
2627
2728#define BUILTIN_MIDX_VERIFY_USAGE \
2829 N_("git multi-pack-index [<options>] verify")
@@ -68,6 +69,8 @@ static struct opts_multi_pack_index {
6869 const char * incremental_base ;
6970 char * refs_snapshot ;
7071 unsigned long batch_size ;
72+ unsigned long max_chain_depth ;
73+ unsigned long split_factor ;
7174 unsigned flags ;
7275 int stdin_packs ;
7376} opts ;
@@ -143,6 +146,20 @@ static void read_packs_from_stdin(struct string_list *to)
143146 strbuf_release (& buf );
144147}
145148
149+ static int parse_positive_ulong (const struct option * opt , const char * arg ,
150+ int unset )
151+ {
152+ unsigned long * value = opt -> value ;
153+
154+ if (unset ) {
155+ * value = 0 ;
156+ return 0 ;
157+ }
158+ if (!arg || !git_parse_ulong (arg , value ) || !* value )
159+ return error (_ ("%s must be greater than zero" ), opt -> long_name );
160+ return 0 ;
161+ }
162+
146163static int cmd_multi_pack_index_write (int argc , const char * * argv ,
147164 const char * prefix ,
148165 struct repository * repo )
@@ -251,6 +268,13 @@ static int cmd_multi_pack_index_compact(int argc, const char **argv,
251268 OPT_NEGBIT (0 , "write-chain-file" , & opts .flags ,
252269 N_ ("write the multi-pack-index chain file" ),
253270 MIDX_WRITE_NO_CHAIN ),
271+ OPT_CALLBACK (0 , "max-chain-depth" , & opts .max_chain_depth ,
272+ N_ ("n" ),
273+ N_ ("automatically compact when the chain has more than this many layers" ),
274+ parse_positive_ulong ),
275+ OPT_CALLBACK (0 , "split-factor" , & opts .split_factor , N_ ("n" ),
276+ N_ ("with --max-chain-depth, compact adjacent layers according to this split factor" ),
277+ parse_positive_ulong ),
254278 OPT_END (),
255279 };
256280
@@ -266,9 +290,18 @@ static int cmd_multi_pack_index_compact(int argc, const char **argv,
266290 options , builtin_multi_pack_index_compact_usage ,
267291 0 );
268292
269- if (argc != 2 )
293+ if (opts .max_chain_depth ) {
294+ if (argc )
295+ usage_with_options (builtin_multi_pack_index_compact_usage ,
296+ options );
297+ } else if (argc != 2 ) {
270298 usage_with_options (builtin_multi_pack_index_compact_usage ,
271299 options );
300+ } else if (opts .split_factor ) {
301+ error (_ ("cannot use --split-factor without --max-chain-depth" ));
302+ usage_with_options (builtin_multi_pack_index_compact_usage ,
303+ options );
304+ }
272305
273306 if (opts .flags & MIDX_WRITE_NO_CHAIN &&
274307 !(opts .flags & MIDX_WRITE_INCREMENTAL )) {
@@ -278,10 +311,38 @@ static int cmd_multi_pack_index_compact(int argc, const char **argv,
278311 options );
279312 }
280313
314+ if (opts .max_chain_depth ) {
315+ if (opts .incremental_base ) {
316+ error (_ ("cannot use --max-chain-depth with --base" ));
317+ usage_with_options (builtin_multi_pack_index_compact_usage ,
318+ options );
319+ }
320+ if (opts .flags & MIDX_WRITE_NO_CHAIN ) {
321+ error (_ ("cannot use --max-chain-depth with --no-write-chain-file" ));
322+ usage_with_options (builtin_multi_pack_index_compact_usage ,
323+ options );
324+ }
325+ if (!opts .split_factor )
326+ opts .split_factor = 2 ;
327+ if (opts .max_chain_depth > UINT32_MAX ||
328+ opts .split_factor > UINT32_MAX ) {
329+ error (_ ("--max-chain-depth and --split-factor must fit in 32 bits" ));
330+ usage_with_options (builtin_multi_pack_index_compact_usage ,
331+ options );
332+ }
333+ opts .flags |= MIDX_WRITE_INCREMENTAL ;
334+ }
335+
281336 source = handle_object_dir_option (the_repository );
282337
283338 FREE_AND_NULL (options );
284339
340+ if (opts .max_chain_depth )
341+ return compact_midx_chain_auto (source ,
342+ (uint32_t )opts .max_chain_depth ,
343+ (uint32_t )opts .split_factor ,
344+ opts .flags );
345+
285346 m = get_multi_pack_index (source );
286347
287348 for (cur = m ; cur && !(from_midx && to_midx ); cur = cur -> base_midx ) {
0 commit comments