@@ -107,311 +107,6 @@ static int repack_config(const char *var, const char *value,
107107 return git_default_config (var , value , ctx , cb );
108108}
109109
110- struct repack_write_midx_opts {
111- struct existing_packs * existing ;
112- struct pack_geometry * geometry ;
113- struct string_list * names ;
114- const char * refs_snapshot ;
115- const char * packdir ;
116- int show_progress ;
117- int write_bitmaps ;
118- int midx_must_contain_cruft ;
119- };
120-
121- static int midx_has_unknown_packs (struct string_list * include ,
122- struct pack_geometry * geometry ,
123- struct existing_packs * existing )
124- {
125- struct string_list_item * item ;
126-
127- string_list_sort (include );
128-
129- for_each_string_list_item (item , & existing -> midx_packs ) {
130- const char * pack_name = item -> string ;
131-
132- /*
133- * Determine whether or not each MIDX'd pack from the existing
134- * MIDX (if any) is represented in the new MIDX. For each pack
135- * in the MIDX, it must either be:
136- *
137- * - In the "include" list of packs to be included in the new
138- * MIDX. Note this function is called before the include
139- * list is populated with any cruft pack(s).
140- *
141- * - Below the geometric split line (if using pack geometry),
142- * indicating that the pack won't be included in the new
143- * MIDX, but its contents were rolled up as part of the
144- * geometric repack.
145- *
146- * - In the existing non-kept packs list (if not using pack
147- * geometry), and marked as non-deleted.
148- */
149- if (string_list_has_string (include , pack_name )) {
150- continue ;
151- } else if (geometry ) {
152- struct strbuf buf = STRBUF_INIT ;
153- uint32_t j ;
154-
155- for (j = 0 ; j < geometry -> split ; j ++ ) {
156- strbuf_reset (& buf );
157- strbuf_addstr (& buf , pack_basename (geometry -> pack [j ]));
158- strbuf_strip_suffix (& buf , ".pack" );
159- strbuf_addstr (& buf , ".idx" );
160-
161- if (!strcmp (pack_name , buf .buf )) {
162- strbuf_release (& buf );
163- break ;
164- }
165- }
166-
167- strbuf_release (& buf );
168-
169- if (j < geometry -> split )
170- continue ;
171- } else {
172- struct string_list_item * item ;
173-
174- item = string_list_lookup (& existing -> non_kept_packs ,
175- pack_name );
176- if (item && !existing_pack_is_marked_for_deletion (item ))
177- continue ;
178- }
179-
180- /*
181- * If we got to this point, the MIDX includes some pack that we
182- * don't know about.
183- */
184- return 1 ;
185- }
186-
187- return 0 ;
188- }
189-
190- static void midx_included_packs (struct string_list * include ,
191- struct repack_write_midx_opts * opts )
192- {
193- struct existing_packs * existing = opts -> existing ;
194- struct pack_geometry * geometry = opts -> geometry ;
195- struct string_list * names = opts -> names ;
196- struct string_list_item * item ;
197- struct strbuf buf = STRBUF_INIT ;
198-
199- for_each_string_list_item (item , & existing -> kept_packs ) {
200- strbuf_reset (& buf );
201- strbuf_addf (& buf , "%s.idx" , item -> string );
202- string_list_insert (include , buf .buf );
203- }
204-
205- for_each_string_list_item (item , names ) {
206- strbuf_reset (& buf );
207- strbuf_addf (& buf , "pack-%s.idx" , item -> string );
208- string_list_insert (include , buf .buf );
209- }
210-
211- if (geometry -> split_factor ) {
212- uint32_t i ;
213-
214- for (i = geometry -> split ; i < geometry -> pack_nr ; i ++ ) {
215- struct packed_git * p = geometry -> pack [i ];
216-
217- /*
218- * The multi-pack index never refers to packfiles part
219- * of an alternate object database, so we skip these.
220- * While git-multi-pack-index(1) would silently ignore
221- * them anyway, this allows us to skip executing the
222- * command completely when we have only non-local
223- * packfiles.
224- */
225- if (!p -> pack_local )
226- continue ;
227-
228- strbuf_reset (& buf );
229- strbuf_addstr (& buf , pack_basename (p ));
230- strbuf_strip_suffix (& buf , ".pack" );
231- strbuf_addstr (& buf , ".idx" );
232-
233- string_list_insert (include , buf .buf );
234- }
235- } else {
236- for_each_string_list_item (item , & existing -> non_kept_packs ) {
237- if (existing_pack_is_marked_for_deletion (item ))
238- continue ;
239-
240- strbuf_reset (& buf );
241- strbuf_addf (& buf , "%s.idx" , item -> string );
242- string_list_insert (include , buf .buf );
243- }
244- }
245-
246- if (opts -> midx_must_contain_cruft ||
247- midx_has_unknown_packs (include , geometry , existing )) {
248- /*
249- * If there are one or more unknown pack(s) present (see
250- * midx_has_unknown_packs() for what makes a pack
251- * "unknown") in the MIDX before the repack, keep them
252- * as they may be required to form a reachability
253- * closure if the MIDX is bitmapped.
254- *
255- * For example, a cruft pack can be required to form a
256- * reachability closure if the MIDX is bitmapped and one
257- * or more of the bitmap's selected commits reaches a
258- * once-cruft object that was later made reachable.
259- */
260- for_each_string_list_item (item , & existing -> cruft_packs ) {
261- /*
262- * When doing a --geometric repack, there is no
263- * need to check for deleted packs, since we're
264- * by definition not doing an ALL_INTO_ONE
265- * repack (hence no packs will be deleted).
266- * Otherwise we must check for and exclude any
267- * packs which are enqueued for deletion.
268- *
269- * So we could omit the conditional below in the
270- * --geometric case, but doing so is unnecessary
271- * since no packs are marked as pending
272- * deletion (since we only call
273- * `existing_packs_mark_for_deletion()` when
274- * doing an all-into-one repack).
275- */
276- if (existing_pack_is_marked_for_deletion (item ))
277- continue ;
278-
279- strbuf_reset (& buf );
280- strbuf_addf (& buf , "%s.idx" , item -> string );
281- string_list_insert (include , buf .buf );
282- }
283- } else {
284- /*
285- * Modern versions of Git (with the appropriate
286- * configuration setting) will write new copies of
287- * once-cruft objects when doing a --geometric repack.
288- *
289- * If the MIDX has no cruft pack, new packs written
290- * during a --geometric repack will not rely on the
291- * cruft pack to form a reachability closure, so we can
292- * avoid including them in the MIDX in that case.
293- */
294- ;
295- }
296-
297- strbuf_release (& buf );
298- }
299-
300- static void remove_redundant_bitmaps (struct string_list * include ,
301- const char * packdir )
302- {
303- struct strbuf path = STRBUF_INIT ;
304- struct string_list_item * item ;
305- size_t packdir_len ;
306-
307- strbuf_addstr (& path , packdir );
308- strbuf_addch (& path , '/' );
309- packdir_len = path .len ;
310-
311- /*
312- * Remove any pack bitmaps corresponding to packs which are now
313- * included in the MIDX.
314- */
315- for_each_string_list_item (item , include ) {
316- strbuf_addstr (& path , item -> string );
317- strbuf_strip_suffix (& path , ".idx" );
318- strbuf_addstr (& path , ".bitmap" );
319-
320- if (unlink (path .buf ) && errno != ENOENT )
321- warning_errno (_ ("could not remove stale bitmap: %s" ),
322- path .buf );
323-
324- strbuf_setlen (& path , packdir_len );
325- }
326- strbuf_release (& path );
327- }
328-
329- static int write_midx_included_packs (struct repack_write_midx_opts * opts )
330- {
331- struct child_process cmd = CHILD_PROCESS_INIT ;
332- struct string_list include = STRING_LIST_INIT_DUP ;
333- struct string_list_item * item ;
334- struct packed_git * preferred = pack_geometry_preferred_pack (opts -> geometry );
335- FILE * in ;
336- int ret = 0 ;
337-
338- midx_included_packs (& include , opts );
339- if (!include .nr )
340- goto done ;
341-
342- cmd .in = -1 ;
343- cmd .git_cmd = 1 ;
344-
345- strvec_push (& cmd .args , "multi-pack-index" );
346- strvec_pushl (& cmd .args , "write" , "--stdin-packs" , NULL );
347-
348- if (opts -> show_progress )
349- strvec_push (& cmd .args , "--progress" );
350- else
351- strvec_push (& cmd .args , "--no-progress" );
352-
353- if (opts -> write_bitmaps )
354- strvec_push (& cmd .args , "--bitmap" );
355-
356- if (preferred )
357- strvec_pushf (& cmd .args , "--preferred-pack=%s" ,
358- pack_basename (preferred ));
359- else if (opts -> names -> nr ) {
360- /* The largest pack was repacked, meaning that either
361- * one or two packs exist depending on whether the
362- * repository has a cruft pack or not.
363- *
364- * Select the non-cruft one as preferred to encourage
365- * pack-reuse among packs containing reachable objects
366- * over unreachable ones.
367- *
368- * (Note we could write multiple packs here if
369- * `--max-pack-size` was given, but any one of them
370- * will suffice, so pick the first one.)
371- */
372- for_each_string_list_item (item , opts -> names ) {
373- struct generated_pack * pack = item -> util ;
374- if (generated_pack_has_ext (pack , ".mtimes" ))
375- continue ;
376-
377- strvec_pushf (& cmd .args , "--preferred-pack=pack-%s.pack" ,
378- item -> string );
379- break ;
380- }
381- } else {
382- /*
383- * No packs were kept, and no packs were written. The
384- * only thing remaining are .keep packs (unless
385- * --pack-kept-objects was given).
386- *
387- * Set the `--preferred-pack` arbitrarily here.
388- */
389- ;
390- }
391-
392- if (opts -> refs_snapshot )
393- strvec_pushf (& cmd .args , "--refs-snapshot=%s" ,
394- opts -> refs_snapshot );
395-
396- ret = start_command (& cmd );
397- if (ret )
398- goto done ;
399-
400- in = xfdopen (cmd .in , "w" );
401- for_each_string_list_item (item , & include )
402- fprintf (in , "%s\n" , item -> string );
403- fclose (in );
404-
405- ret = finish_command (& cmd );
406- done :
407- if (!ret && opts -> write_bitmaps )
408- remove_redundant_bitmaps (& include , opts -> packdir );
409-
410- string_list_clear (& include , 0 );
411-
412- return ret ;
413- }
414-
415110static int finish_pack_objects_cmd (const struct git_hash_algo * algop ,
416111 struct child_process * cmd ,
417112 struct string_list * names ,
0 commit comments