|
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" |
23 | 25 |
|
24 | 26 | static const char *pack_usage[] = { |
25 | 27 | N_("git pack-objects --stdout [options...] [< ref-list | < object-list]"), |
@@ -2407,13 +2409,24 @@ static int has_sha1_pack_kept_or_nonlocal(const unsigned char *sha1) |
2407 | 2409 | return 0; |
2408 | 2410 | } |
2409 | 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 | + |
2410 | 2421 | static int loosened_object_can_be_discarded(const unsigned char *sha1, |
2411 | 2422 | unsigned long mtime) |
2412 | 2423 | { |
2413 | 2424 | if (!unpack_unreachable_expiration) |
2414 | 2425 | return 0; |
2415 | 2426 | if (mtime > unpack_unreachable_expiration) |
2416 | 2427 | return 0; |
| 2428 | + if (sha1_array_lookup(&recent_objects, sha1) >= 0) |
| 2429 | + return 0; |
2417 | 2430 | return 1; |
2418 | 2431 | } |
2419 | 2432 |
|
@@ -2470,6 +2483,19 @@ static int get_object_list_from_bitmap(struct rev_info *revs) |
2470 | 2483 | return 0; |
2471 | 2484 | } |
2472 | 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 | + |
2473 | 2499 | static void get_object_list(int ac, const char **av) |
2474 | 2500 | { |
2475 | 2501 | struct rev_info revs; |
@@ -2517,10 +2543,23 @@ static void get_object_list(int ac, const char **av) |
2517 | 2543 | mark_edges_uninteresting(&revs, show_edge); |
2518 | 2544 | traverse_commit_list(&revs, show_commit, show_object, NULL); |
2519 | 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 | + |
2520 | 2557 | if (keep_unreachable) |
2521 | 2558 | add_objects_in_unpacked_packs(&revs); |
2522 | 2559 | if (unpack_unreachable) |
2523 | 2560 | loosen_unused_packed_objects(&revs); |
| 2561 | + |
| 2562 | + sha1_array_clear(&recent_objects); |
2524 | 2563 | } |
2525 | 2564 |
|
2526 | 2565 | static int option_parse_index_version(const struct option *opt, |
|
0 commit comments