@@ -100,6 +100,18 @@ struct write_midx_context {
100
100
struct string_list * to_include ;
101
101
};
102
102
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
+
103
115
static void add_pack_to_midx (const char * full_path , size_t full_path_len ,
104
116
const char * file_name , void * data )
105
117
{
@@ -108,29 +120,11 @@ static void add_pack_to_midx(const char *full_path, size_t full_path_len,
108
120
109
121
if (ends_with (file_name , ".idx" )) {
110
122
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 ))
130
125
return ;
131
126
132
127
ALLOC_GROW (ctx -> info , ctx -> nr + 1 , ctx -> alloc );
133
-
134
128
p = add_packed_git (full_path , full_path_len , 0 );
135
129
if (!p ) {
136
130
warning (_ ("failed to add packfile '%s'" ),
@@ -299,21 +293,16 @@ static void midx_fanout_add_pack_fanout(struct midx_fanout *fanout,
299
293
* Copy only the de-duplicated entries (selected by most-recent modified time
300
294
* of a packfile containing the object).
301
295
*/
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 )
307
298
{
308
299
uint32_t cur_fanout , cur_pack , cur_object ;
309
300
size_t alloc_objects , total_objects = 0 ;
310
301
struct midx_fanout fanout = { 0 };
311
- struct pack_midx_entry * deduplicated_entries = NULL ;
312
- uint32_t start_pack = m ? m -> num_packs : 0 ;
313
302
314
- for (cur_pack = start_pack ; cur_pack < nr_packs ; cur_pack ++ )
303
+ for (cur_pack = start_pack ; cur_pack < ctx -> nr ; cur_pack ++ )
315
304
total_objects = st_add (total_objects ,
316
- info [cur_pack ].p -> num_objects );
305
+ ctx -> info [cur_pack ].p -> num_objects );
317
306
318
307
/*
319
308
* 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,
323
312
alloc_objects = fanout .alloc = total_objects > 3200 ? total_objects / 200 : 16 ;
324
313
325
314
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 ;
328
317
329
318
for (cur_fanout = 0 ; cur_fanout < 256 ; cur_fanout ++ ) {
330
319
fanout .nr = 0 ;
331
320
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 );
335
324
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 ;
338
327
midx_fanout_add_pack_fanout (& fanout ,
339
- info , cur_pack ,
328
+ ctx -> info , cur_pack ,
340
329
preferred , cur_fanout );
341
330
}
342
331
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 ,
346
335
cur_fanout );
347
336
348
337
midx_fanout_sort (& fanout );
@@ -356,17 +345,16 @@ static struct pack_midx_entry *get_sorted_entries(struct multi_pack_index *m,
356
345
& fanout .entries [cur_object ].oid ))
357
346
continue ;
358
347
359
- ALLOC_GROW (deduplicated_entries , st_add (* nr_objects , 1 ),
348
+ ALLOC_GROW (ctx -> entries , st_add (ctx -> entries_nr , 1 ),
360
349
alloc_objects );
361
- memcpy (& deduplicated_entries [ * nr_objects ],
350
+ memcpy (& ctx -> entries [ ctx -> entries_nr ],
362
351
& fanout .entries [cur_object ],
363
352
sizeof (struct pack_midx_entry ));
364
- ( * nr_objects ) ++ ;
353
+ ctx -> entries_nr ++ ;
365
354
}
366
355
}
367
356
368
357
free (fanout .entries );
369
- return deduplicated_entries ;
370
358
}
371
359
372
360
static 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,
886
874
return result ;
887
875
}
888
876
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
+
889
914
static int write_midx_internal (const char * object_dir ,
890
915
struct string_list * packs_to_include ,
891
916
struct string_list * packs_to_drop ,
@@ -895,7 +920,7 @@ static int write_midx_internal(const char *object_dir,
895
920
{
896
921
struct strbuf midx_name = STRBUF_INIT ;
897
922
unsigned char midx_hash [GIT_MAX_RAWSZ ];
898
- uint32_t i ;
923
+ uint32_t i , start_pack ;
899
924
struct hashfile * f = NULL ;
900
925
struct lock_file lk ;
901
926
struct write_midx_context ctx = { 0 };
@@ -912,15 +937,7 @@ static int write_midx_internal(const char *object_dir,
912
937
die_errno (_ ("unable to create leading directories of %s" ),
913
938
midx_name .buf );
914
939
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 );
924
941
if (ctx .m && !midx_checksum_valid (ctx .m )) {
925
942
warning (_ ("ignoring existing multi-pack-index; checksum mismatch" ));
926
943
ctx .m = NULL ;
@@ -929,42 +946,23 @@ static int write_midx_internal(const char *object_dir,
929
946
ctx .nr = 0 ;
930
947
ctx .alloc = ctx .m ? ctx .m -> num_packs : 16 ;
931
948
ctx .info = NULL ;
949
+ ctx .to_include = packs_to_include ;
932
950
ALLOC_ARRAY (ctx .info , ctx .alloc );
933
951
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 ;
958
956
}
959
957
958
+ start_pack = ctx .nr ;
959
+
960
960
ctx .pack_paths_checked = 0 ;
961
961
if (flags & MIDX_PROGRESS )
962
962
ctx .progress = start_delayed_progress (_ ("Adding packfiles to multi-pack-index" ), 0 );
963
963
else
964
964
ctx .progress = NULL ;
965
965
966
- ctx .to_include = packs_to_include ;
967
-
968
966
for_each_file_in_pack_dir (object_dir , add_pack_to_midx , & ctx );
969
967
stop_progress (& ctx .progress );
970
968
@@ -1054,8 +1052,7 @@ static int write_midx_internal(const char *object_dir,
1054
1052
}
1055
1053
}
1056
1054
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 );
1059
1056
1060
1057
ctx .large_offsets_needed = 0 ;
1061
1058
for (i = 0 ; i < ctx .entries_nr ; i ++ ) {
0 commit comments