20
20
#include "streaming.h"
21
21
#include "thread-utils.h"
22
22
#include "pack-bitmap.h"
23
+ #include "reachable.h"
24
+ #include "sha1-array.h"
25
+ #include "argv-array.h"
23
26
24
27
static const char * pack_usage [] = {
25
28
N_ ("git pack-objects --stdout [options...] [< ref-list | < object-list]" ),
@@ -2406,6 +2409,27 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1)
2406
2409
return 0 ;
2407
2410
}
2408
2411
2412
+ /*
2413
+ * Store a list of sha1s that are should not be discarded
2414
+ * because they are either written too recently, or are
2415
+ * reachable from another object that was.
2416
+ *
2417
+ * This is filled by get_object_list.
2418
+ */
2419
+ static struct sha1_array recent_objects ;
2420
+
2421
+ static int loosened_object_can_be_discarded (const unsigned char * sha1 ,
2422
+ unsigned long mtime )
2423
+ {
2424
+ if (!unpack_unreachable_expiration )
2425
+ return 0 ;
2426
+ if (mtime > unpack_unreachable_expiration )
2427
+ return 0 ;
2428
+ if (sha1_array_lookup (& recent_objects , sha1 ) >= 0 )
2429
+ return 0 ;
2430
+ return 1 ;
2431
+ }
2432
+
2409
2433
static void loosen_unused_packed_objects (struct rev_info * revs )
2410
2434
{
2411
2435
struct packed_git * p ;
@@ -2416,17 +2440,14 @@ static void loosen_unused_packed_objects(struct rev_info *revs)
2416
2440
if (!p -> pack_local || p -> pack_keep )
2417
2441
continue ;
2418
2442
2419
- if (unpack_unreachable_expiration &&
2420
- p -> mtime < unpack_unreachable_expiration )
2421
- continue ;
2422
-
2423
2443
if (open_pack_index (p ))
2424
2444
die ("cannot open pack index" );
2425
2445
2426
2446
for (i = 0 ; i < p -> num_objects ; i ++ ) {
2427
2447
sha1 = nth_packed_object_sha1 (p , i );
2428
2448
if (!packlist_find (& to_pack , sha1 , NULL ) &&
2429
- !has_sha1_pack_kept_or_nonlocal (sha1 ))
2449
+ !has_sha1_pack_kept_or_nonlocal (sha1 ) &&
2450
+ !loosened_object_can_be_discarded (sha1 , p -> mtime ))
2430
2451
if (force_object_loose (sha1 , p -> mtime ))
2431
2452
die ("unable to force loose object" );
2432
2453
}
@@ -2462,6 +2483,19 @@ static int get_object_list_from_bitmap(struct rev_info *revs)
2462
2483
return 0 ;
2463
2484
}
2464
2485
2486
+ static void record_recent_object (struct object * obj ,
2487
+ const struct name_path * path ,
2488
+ const char * last ,
2489
+ void * data )
2490
+ {
2491
+ sha1_array_append (& recent_objects , obj -> sha1 );
2492
+ }
2493
+
2494
+ static void record_recent_commit (struct commit * commit , void * data )
2495
+ {
2496
+ sha1_array_append (& recent_objects , commit -> object .sha1 );
2497
+ }
2498
+
2465
2499
static void get_object_list (int ac , const char * * av )
2466
2500
{
2467
2501
struct rev_info revs ;
@@ -2509,10 +2543,23 @@ static void get_object_list(int ac, const char **av)
2509
2543
mark_edges_uninteresting (& revs , show_edge );
2510
2544
traverse_commit_list (& revs , show_commit , show_object , NULL );
2511
2545
2546
+ if (unpack_unreachable_expiration ) {
2547
+ revs .ignore_missing_links = 1 ;
2548
+ if (add_unseen_recent_objects_to_traversal (& revs ,
2549
+ unpack_unreachable_expiration ))
2550
+ die ("unable to add recent objects" );
2551
+ if (prepare_revision_walk (& revs ))
2552
+ die ("revision walk setup failed" );
2553
+ traverse_commit_list (& revs , record_recent_commit ,
2554
+ record_recent_object , NULL );
2555
+ }
2556
+
2512
2557
if (keep_unreachable )
2513
2558
add_objects_in_unpacked_packs (& revs );
2514
2559
if (unpack_unreachable )
2515
2560
loosen_unused_packed_objects (& revs );
2561
+
2562
+ sha1_array_clear (& recent_objects );
2516
2563
}
2517
2564
2518
2565
static int option_parse_index_version (const struct option * opt ,
@@ -2567,9 +2614,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
2567
2614
int use_internal_rev_list = 0 ;
2568
2615
int thin = 0 ;
2569
2616
int all_progress_implied = 0 ;
2570
- const char * rp_av [6 ];
2571
- int rp_ac = 0 ;
2617
+ struct argv_array rp = ARGV_ARRAY_INIT ;
2572
2618
int rev_list_unpacked = 0 , rev_list_all = 0 , rev_list_reflog = 0 ;
2619
+ int rev_list_index = 0 ;
2573
2620
struct option pack_objects_options [] = {
2574
2621
OPT_SET_INT ('q' , "quiet" , & progress ,
2575
2622
N_ ("do not show progress meter" ), 0 ),
@@ -2616,6 +2663,9 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
2616
2663
{ OPTION_SET_INT , 0 , "reflog" , & rev_list_reflog , NULL ,
2617
2664
N_ ("include objects referred by reflog entries" ),
2618
2665
PARSE_OPT_NOARG | PARSE_OPT_NONEG , NULL , 1 },
2666
+ { OPTION_SET_INT , 0 , "indexed-objects" , & rev_list_index , NULL ,
2667
+ N_ ("include objects referred to by the index" ),
2668
+ PARSE_OPT_NOARG | PARSE_OPT_NONEG , NULL , 1 },
2619
2669
OPT_BOOL (0 , "stdout" , & pack_to_stdout ,
2620
2670
N_ ("output pack to stdout" )),
2621
2671
OPT_BOOL (0 , "include-tag" , & include_tag ,
@@ -2658,24 +2708,28 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
2658
2708
if (pack_to_stdout != !base_name || argc )
2659
2709
usage_with_options (pack_usage , pack_objects_options );
2660
2710
2661
- rp_av [ rp_ac ++ ] = "pack-objects" ;
2711
+ argv_array_push ( & rp , "pack-objects" ) ;
2662
2712
if (thin ) {
2663
2713
use_internal_rev_list = 1 ;
2664
- rp_av [ rp_ac ++ ] = "--objects-edge" ;
2714
+ argv_array_push ( & rp , "--objects-edge" ) ;
2665
2715
} else
2666
- rp_av [ rp_ac ++ ] = "--objects" ;
2716
+ argv_array_push ( & rp , "--objects" ) ;
2667
2717
2668
2718
if (rev_list_all ) {
2669
2719
use_internal_rev_list = 1 ;
2670
- rp_av [ rp_ac ++ ] = "--all" ;
2720
+ argv_array_push ( & rp , "--all" ) ;
2671
2721
}
2672
2722
if (rev_list_reflog ) {
2673
2723
use_internal_rev_list = 1 ;
2674
- rp_av [rp_ac ++ ] = "--reflog" ;
2724
+ argv_array_push (& rp , "--reflog" );
2725
+ }
2726
+ if (rev_list_index ) {
2727
+ use_internal_rev_list = 1 ;
2728
+ argv_array_push (& rp , "--indexed-objects" );
2675
2729
}
2676
2730
if (rev_list_unpacked ) {
2677
2731
use_internal_rev_list = 1 ;
2678
- rp_av [ rp_ac ++ ] = "--unpacked" ;
2732
+ argv_array_push ( & rp , "--unpacked" ) ;
2679
2733
}
2680
2734
2681
2735
if (!reuse_object )
@@ -2706,6 +2760,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
2706
2760
2707
2761
if (keep_unreachable && unpack_unreachable )
2708
2762
die ("--keep-unreachable and --unpack-unreachable are incompatible." );
2763
+ if (!rev_list_all || !rev_list_reflog || !rev_list_index )
2764
+ unpack_unreachable_expiration = 0 ;
2709
2765
2710
2766
if (!use_internal_rev_list || !pack_to_stdout || is_repository_shallow ())
2711
2767
use_bitmap_index = 0 ;
@@ -2723,8 +2779,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix)
2723
2779
if (!use_internal_rev_list )
2724
2780
read_object_list_from_stdin ();
2725
2781
else {
2726
- rp_av [ rp_ac ] = NULL ;
2727
- get_object_list ( rp_ac , rp_av );
2782
+ get_object_list ( rp . argc , rp . argv ) ;
2783
+ argv_array_clear ( & rp );
2728
2784
}
2729
2785
cleanup_preferred_base ();
2730
2786
if (include_tag && nr_result )
0 commit comments