@@ -202,6 +202,37 @@ static int write_oid(const struct object_id *oid, struct packed_git *pack,
202
202
return 0 ;
203
203
}
204
204
205
+ static struct {
206
+ const char * name ;
207
+ unsigned optional :1 ;
208
+ } exts [] = {
209
+ {".pack" },
210
+ {".idx" },
211
+ {".bitmap" , 1 },
212
+ {".promisor" , 1 },
213
+ };
214
+
215
+ static unsigned populate_pack_exts (char * name )
216
+ {
217
+ struct stat statbuf ;
218
+ struct strbuf path = STRBUF_INIT ;
219
+ unsigned ret = 0 ;
220
+ int i ;
221
+
222
+ for (i = 0 ; i < ARRAY_SIZE (exts ); i ++ ) {
223
+ strbuf_reset (& path );
224
+ strbuf_addf (& path , "%s-%s%s" , packtmp , name , exts [i ].name );
225
+
226
+ if (stat (path .buf , & statbuf ))
227
+ continue ;
228
+
229
+ ret |= (1 << i );
230
+ }
231
+
232
+ strbuf_release (& path );
233
+ return ret ;
234
+ }
235
+
205
236
static void repack_promisor_objects (const struct pack_objects_args * args ,
206
237
struct string_list * names )
207
238
{
@@ -230,11 +261,12 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
230
261
231
262
out = xfdopen (cmd .out , "r" );
232
263
while (strbuf_getline_lf (& line , out ) != EOF ) {
264
+ struct string_list_item * item ;
233
265
char * promisor_name ;
234
266
int fd ;
235
267
if (line .len != the_hash_algo -> hexsz )
236
268
die (_ ("repack: Expecting full hex object ID lines only from pack-objects." ));
237
- string_list_append (names , line .buf );
269
+ item = string_list_append (names , line .buf );
238
270
239
271
/*
240
272
* pack-objects creates the .pack and .idx files, but not the
@@ -253,6 +285,9 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
253
285
if (fd < 0 )
254
286
die_errno (_ ("unable to create '%s'" ), promisor_name );
255
287
close (fd );
288
+
289
+ item -> util = (void * )(uintptr_t )populate_pack_exts (item -> string );
290
+
256
291
free (promisor_name );
257
292
}
258
293
fclose (out );
@@ -265,22 +300,13 @@ static void repack_promisor_objects(const struct pack_objects_args *args,
265
300
266
301
int cmd_repack (int argc , const char * * argv , const char * prefix )
267
302
{
268
- struct {
269
- const char * name ;
270
- unsigned optional :1 ;
271
- } exts [] = {
272
- {".pack" },
273
- {".idx" },
274
- {".bitmap" , 1 },
275
- {".promisor" , 1 },
276
- };
277
303
struct child_process cmd = CHILD_PROCESS_INIT ;
278
304
struct string_list_item * item ;
279
305
struct string_list names = STRING_LIST_INIT_DUP ;
280
306
struct string_list rollback = STRING_LIST_INIT_NODUP ;
281
307
struct string_list existing_packs = STRING_LIST_INIT_DUP ;
282
308
struct strbuf line = STRBUF_INIT ;
283
- int i , ext , ret , failed ;
309
+ int i , ext , ret ;
284
310
FILE * out ;
285
311
286
312
/* variables to be filled by option parsing */
@@ -429,113 +455,42 @@ int cmd_repack(int argc, const char **argv, const char *prefix)
429
455
if (!names .nr && !po_args .quiet )
430
456
printf_ln (_ ("Nothing new to pack." ));
431
457
458
+ for_each_string_list_item (item , & names ) {
459
+ item -> util = (void * )(uintptr_t )populate_pack_exts (item -> string );
460
+ }
461
+
432
462
close_object_store (the_repository -> objects );
433
463
434
464
/*
435
465
* Ok we have prepared all new packfiles.
436
- * First see if there are packs of the same name and if so
437
- * if we can move them out of the way (this can happen if we
438
- * repacked immediately after packing fully.
439
466
*/
440
- failed = 0 ;
441
467
for_each_string_list_item (item , & names ) {
442
468
for (ext = 0 ; ext < ARRAY_SIZE (exts ); ext ++ ) {
443
469
char * fname , * fname_old ;
444
470
445
- fname = mkpathdup ("%s/pack-%s%s" , packdir ,
446
- item -> string , exts [ext ].name );
447
- if (!file_exists (fname )) {
448
- free (fname );
449
- continue ;
450
- }
451
-
452
- fname_old = mkpathdup ("%s/old-%s%s" , packdir ,
453
- item -> string , exts [ext ].name );
454
- if (file_exists (fname_old ))
455
- if (unlink (fname_old ))
456
- failed = 1 ;
457
-
458
- if (!failed && rename (fname , fname_old )) {
459
- free (fname );
460
- free (fname_old );
461
- failed = 1 ;
462
- break ;
463
- } else {
464
- string_list_append (& rollback , fname );
465
- free (fname_old );
466
- }
467
- }
468
- if (failed )
469
- break ;
470
- }
471
- if (failed ) {
472
- struct string_list rollback_failure = STRING_LIST_INIT_DUP ;
473
- for_each_string_list_item (item , & rollback ) {
474
- char * fname , * fname_old ;
475
- fname = mkpathdup ("%s/%s" , packdir , item -> string );
476
- fname_old = mkpathdup ("%s/old-%s" , packdir , item -> string );
477
- if (rename (fname_old , fname ))
478
- string_list_append (& rollback_failure , fname );
479
- free (fname );
480
- free (fname_old );
481
- }
482
-
483
- if (rollback_failure .nr ) {
484
- int i ;
485
- fprintf (stderr ,
486
- _ ("WARNING: Some packs in use have been renamed by\n"
487
- "WARNING: prefixing old- to their name, in order to\n"
488
- "WARNING: replace them with the new version of the\n"
489
- "WARNING: file. But the operation failed, and the\n"
490
- "WARNING: attempt to rename them back to their\n"
491
- "WARNING: original names also failed.\n"
492
- "WARNING: Please rename them in %s manually:\n" ), packdir );
493
- for (i = 0 ; i < rollback_failure .nr ; i ++ )
494
- fprintf (stderr , "WARNING: old-%s -> %s\n" ,
495
- rollback_failure .items [i ].string ,
496
- rollback_failure .items [i ].string );
497
- }
498
- exit (1 );
499
- }
500
-
501
- /* Now the ones with the same name are out of the way... */
502
- for_each_string_list_item (item , & names ) {
503
- for (ext = 0 ; ext < ARRAY_SIZE (exts ); ext ++ ) {
504
- char * fname , * fname_old ;
505
- struct stat statbuffer ;
506
- int exists = 0 ;
507
471
fname = mkpathdup ("%s/pack-%s%s" ,
508
472
packdir , item -> string , exts [ext ].name );
509
473
fname_old = mkpathdup ("%s-%s%s" ,
510
474
packtmp , item -> string , exts [ext ].name );
511
- if (!stat (fname_old , & statbuffer )) {
512
- statbuffer .st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH );
513
- chmod (fname_old , statbuffer .st_mode );
514
- exists = 1 ;
515
- }
516
- if (exists || !exts [ext ].optional ) {
475
+
476
+ if (((uintptr_t )item -> util ) & (1 << ext )) {
477
+ struct stat statbuffer ;
478
+ if (!stat (fname_old , & statbuffer )) {
479
+ statbuffer .st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH );
480
+ chmod (fname_old , statbuffer .st_mode );
481
+ }
482
+
517
483
if (rename (fname_old , fname ))
518
484
die_errno (_ ("renaming '%s' failed" ), fname_old );
519
- }
520
- free (fname );
521
- free (fname_old );
522
- }
523
- }
485
+ } else if (!exts [ext ].optional )
486
+ die (_ ("missing required file: %s" ), fname_old );
487
+ else if (unlink (fname ) < 0 && errno != ENOENT )
488
+ die_errno (_ ("could not unlink: %s" ), fname );
524
489
525
- /* Remove the "old-" files */
526
- for_each_string_list_item (item , & names ) {
527
- for (ext = 0 ; ext < ARRAY_SIZE (exts ); ext ++ ) {
528
- char * fname ;
529
- fname = mkpathdup ("%s/old-%s%s" ,
530
- packdir ,
531
- item -> string ,
532
- exts [ext ].name );
533
- if (remove_path (fname ))
534
- warning (_ ("failed to remove '%s'" ), fname );
535
490
free (fname );
491
+ free (fname_old );
536
492
}
537
493
}
538
-
539
494
/* End of pack replacement. */
540
495
541
496
reprepare_packed_git (the_repository );
0 commit comments