@@ -100,6 +100,18 @@ struct write_midx_context {
100100 struct string_list * to_include ;
101101};
102102
103+ static int should_include_pack (const struct write_midx_context * ctx ,
104+ const char * file_name ,
105+ int exclude_from_midx )
106+ {
107+ if (exclude_from_midx && ctx -> m && midx_contains_pack (ctx -> m , file_name ))
108+ return 0 ;
109+ if (ctx -> to_include && !string_list_has_string (ctx -> to_include ,
110+ file_name ))
111+ return 0 ;
112+ return 1 ;
113+ }
114+
103115static void add_pack_to_midx (const char * full_path , size_t full_path_len ,
104116 const char * file_name , void * data )
105117{
@@ -108,29 +120,11 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len,
108120
109121 if (ends_with (file_name , ".idx" )) {
110122 display_progress (ctx -> progress , ++ ctx -> pack_paths_checked );
111- /*
112- * Note that at most one of ctx->m and ctx->to_include are set,
113- * so we are testing midx_contains_pack() and
114- * string_list_has_string() independently (guarded by the
115- * appropriate NULL checks).
116- *
117- * We could support passing to_include while reusing an existing
118- * MIDX, but don't currently since the reuse process drags
119- * forward all packs from an existing MIDX (without checking
120- * whether or not they appear in the to_include list).
121- *
122- * If we added support for that, these next two conditional
123- * should be performed independently (likely checking
124- * to_include before the existing MIDX).
125- */
126- if (ctx -> m && midx_contains_pack (ctx -> m , file_name ))
127- return ;
128- else if (ctx -> to_include &&
129- !string_list_has_string (ctx -> to_include , file_name ))
123+
124+ if (!should_include_pack (ctx , file_name , 1 ))
130125 return ;
131126
132127 ALLOC_GROW (ctx -> info , ctx -> nr + 1 , ctx -> alloc );
133-
134128 p = add_packed_git (full_path , full_path_len , 0 );
135129 if (!p ) {
136130 warning (_ ("failed to add packfile '%s'" ),
@@ -299,21 +293,16 @@ static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
299293 * Copy only the de-duplicated entries (selected by most-recent modified time
300294 * of a packfile containing the object).
301295 */
302- static struct pack_midx_entry * get_sorted_entries (struct multi_pack_index * m ,
303- struct pack_info * info ,
304- uint32_t nr_packs ,
305- size_t * nr_objects ,
306- int preferred_pack )
296+ static void compute_sorted_entries (struct write_midx_context * ctx ,
297+ uint32_t start_pack )
307298{
308299 uint32_t cur_fanout , cur_pack , cur_object ;
309300 size_t alloc_objects , total_objects = 0 ;
310301 struct midx_fanout fanout = { 0 };
311- struct pack_midx_entry * deduplicated_entries = NULL ;
312- uint32_t start_pack = m ? m -> num_packs : 0 ;
313302
314- for (cur_pack = start_pack ; cur_pack < nr_packs ; cur_pack ++ )
303+ for (cur_pack = start_pack ; cur_pack < ctx -> nr ; cur_pack ++ )
315304 total_objects = st_add (total_objects ,
316- info [cur_pack ].p -> num_objects );
305+ ctx -> info [cur_pack ].p -> num_objects );
317306
318307 /*
319308 * As we de-duplicate by fanout value, we expect the fanout
@@ -323,26 +312,26 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
323312 alloc_objects = fanout .alloc = total_objects > 3200 ? total_objects / 200 : 16 ;
324313
325314 ALLOC_ARRAY (fanout .entries , fanout .alloc );
326- ALLOC_ARRAY (deduplicated_entries , alloc_objects );
327- * nr_objects = 0 ;
315+ ALLOC_ARRAY (ctx -> entries , alloc_objects );
316+ ctx -> entries_nr = 0 ;
328317
329318 for (cur_fanout = 0 ; cur_fanout < 256 ; cur_fanout ++ ) {
330319 fanout .nr = 0 ;
331320
332- if (m )
333- midx_fanout_add_midx_fanout (& fanout , m , cur_fanout ,
334- preferred_pack );
321+ if (ctx -> m )
322+ midx_fanout_add_midx_fanout (& fanout , ctx -> m , cur_fanout ,
323+ ctx -> preferred_pack_idx );
335324
336- for (cur_pack = start_pack ; cur_pack < nr_packs ; cur_pack ++ ) {
337- int preferred = cur_pack == preferred_pack ;
325+ for (cur_pack = start_pack ; cur_pack < ctx -> nr ; cur_pack ++ ) {
326+ int preferred = cur_pack == ctx -> preferred_pack_idx ;
338327 midx_fanout_add_pack_fanout (& fanout ,
339- info , cur_pack ,
328+ ctx -> info , cur_pack ,
340329 preferred , cur_fanout );
341330 }
342331
343- if (-1 < preferred_pack && preferred_pack < start_pack )
344- midx_fanout_add_pack_fanout (& fanout , info ,
345- preferred_pack , 1 ,
332+ if (-1 < ctx -> preferred_pack_idx && ctx -> preferred_pack_idx < start_pack )
333+ midx_fanout_add_pack_fanout (& fanout , ctx -> info ,
334+ ctx -> preferred_pack_idx , 1 ,
346335 cur_fanout );
347336
348337 midx_fanout_sort (& fanout );
@@ -356,17 +345,16 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
356345 & fanout .entries [cur_object ].oid ))
357346 continue ;
358347
359- ALLOC_GROW (deduplicated_entries , st_add (* nr_objects , 1 ),
348+ ALLOC_GROW (ctx -> entries , st_add (ctx -> entries_nr , 1 ),
360349 alloc_objects );
361- memcpy (& deduplicated_entries [ * nr_objects ],
350+ memcpy (& ctx -> entries [ ctx -> entries_nr ],
362351 & fanout .entries [cur_object ],
363352 sizeof (struct pack_midx_entry ));
364- ( * nr_objects ) ++ ;
353+ ctx -> entries_nr ++ ;
365354 }
366355 }
367356
368357 free (fanout .entries );
369- return deduplicated_entries ;
370358}
371359
372360static int write_midx_pack_names (struct hashfile * f , void * data )
@@ -886,6 +874,43 @@ static struct multi_pack_index *lookup_multi_pack_index(struct repository *r,
886874 return result ;
887875}
888876
877+ static int fill_packs_from_midx (struct write_midx_context * ctx ,
878+ const char * preferred_pack_name , uint32_t flags )
879+ {
880+ uint32_t i ;
881+
882+ for (i = 0 ; i < ctx -> m -> num_packs ; i ++ ) {
883+ if (!should_include_pack (ctx , ctx -> m -> pack_names [i ], 0 ))
884+ continue ;
885+
886+ ALLOC_GROW (ctx -> info , ctx -> nr + 1 , ctx -> alloc );
887+
888+ if (flags & MIDX_WRITE_REV_INDEX || preferred_pack_name ) {
889+ /*
890+ * If generating a reverse index, need to have
891+ * packed_git's loaded to compare their
892+ * mtimes and object count.
893+ *
894+ *
895+ * If a preferred pack is specified, need to
896+ * have packed_git's loaded to ensure the chosen
897+ * preferred pack has a non-zero object count.
898+ */
899+ if (prepare_midx_pack (the_repository , ctx -> m , i ))
900+ return error (_ ("could not load pack" ));
901+
902+ if (open_pack_index (ctx -> m -> packs [i ]))
903+ die (_ ("could not open index for %s" ),
904+ ctx -> m -> packs [i ]-> pack_name );
905+ }
906+
907+ fill_pack_info (& ctx -> info [ctx -> nr ++ ], ctx -> m -> packs [i ],
908+ ctx -> m -> pack_names [i ], i );
909+ }
910+
911+ return 0 ;
912+ }
913+
889914static int write_midx_internal (const char * object_dir ,
890915 struct string_list * packs_to_include ,
891916 struct string_list * packs_to_drop ,
@@ -895,7 +920,7 @@ static int write_midx_internal(const char *object_dir,
895920{
896921 struct strbuf midx_name = STRBUF_INIT ;
897922 unsigned char midx_hash [GIT_MAX_RAWSZ ];
898- uint32_t i ;
923+ uint32_t i , start_pack ;
899924 struct hashfile * f = NULL ;
900925 struct lock_file lk ;
901926 struct write_midx_context ctx = { 0 };
@@ -912,15 +937,7 @@ static int write_midx_internal(const char *object_dir,
912937 die_errno (_ ("unable to create leading directories of %s" ),
913938 midx_name .buf );
914939
915- if (!packs_to_include ) {
916- /*
917- * Only reference an existing MIDX when not filtering which
918- * packs to include, since all packs and objects are copied
919- * blindly from an existing MIDX if one is present.
920- */
921- ctx .m = lookup_multi_pack_index (the_repository , object_dir );
922- }
923-
940+ ctx .m = lookup_multi_pack_index (the_repository , object_dir );
924941 if (ctx .m && !midx_checksum_valid (ctx .m )) {
925942 warning (_ ("ignoring existing multi-pack-index; checksum mismatch" ));
926943 ctx .m = NULL ;
@@ -929,42 +946,23 @@ static int write_midx_internal(const char *object_dir,
929946 ctx .nr = 0 ;
930947 ctx .alloc = ctx .m ? ctx .m -> num_packs : 16 ;
931948 ctx .info = NULL ;
949+ ctx .to_include = packs_to_include ;
932950 ALLOC_ARRAY (ctx .info , ctx .alloc );
933951
934- if (ctx .m ) {
935- for (i = 0 ; i < ctx .m -> num_packs ; i ++ ) {
936- ALLOC_GROW (ctx .info , ctx .nr + 1 , ctx .alloc );
937-
938- if (flags & MIDX_WRITE_REV_INDEX ) {
939- /*
940- * If generating a reverse index, need to have
941- * packed_git's loaded to compare their
942- * mtimes and object count.
943- */
944- if (prepare_midx_pack (the_repository , ctx .m , i )) {
945- error (_ ("could not load pack" ));
946- result = 1 ;
947- goto cleanup ;
948- }
949-
950- if (open_pack_index (ctx .m -> packs [i ]))
951- die (_ ("could not open index for %s" ),
952- ctx .m -> packs [i ]-> pack_name );
953- }
954-
955- fill_pack_info (& ctx .info [ctx .nr ++ ], ctx .m -> packs [i ],
956- ctx .m -> pack_names [i ], i );
957- }
952+ if (ctx .m && fill_packs_from_midx (& ctx , preferred_pack_name ,
953+ flags ) < 0 ) {
954+ result = 1 ;
955+ goto cleanup ;
958956 }
959957
958+ start_pack = ctx .nr ;
959+
960960 ctx .pack_paths_checked = 0 ;
961961 if (flags & MIDX_PROGRESS )
962962 ctx .progress = start_delayed_progress (_ ("Adding packfiles to multi-pack-index" ), 0 );
963963 else
964964 ctx .progress = NULL ;
965965
966- ctx .to_include = packs_to_include ;
967-
968966 for_each_file_in_pack_dir (object_dir , add_pack_to_midx , & ctx );
969967 stop_progress (& ctx .progress );
970968
@@ -1054,8 +1052,7 @@ static int write_midx_internal(const char *object_dir,
10541052 }
10551053 }
10561054
1057- ctx .entries = get_sorted_entries (ctx .m , ctx .info , ctx .nr , & ctx .entries_nr ,
1058- ctx .preferred_pack_idx );
1055+ compute_sorted_entries (& ctx , start_pack );
10591056
10601057 ctx .large_offsets_needed = 0 ;
10611058 for (i = 0 ; i < ctx .entries_nr ; i ++ ) {
0 commit comments