mirror of
https://github.com/git/git.git
synced 2024-11-27 12:03:55 +08:00
a7d493833f
In a previous patch, pack-objects learned how to generate a cruft pack so long as no objects are dropped. This patch teaches pack-objects to handle the case where a non-never `--cruft-expiration` value is passed. This case is slightly more complicated than before, because we want pack-objects to save unreachable objects which would have been pruned when there is another recent (i.e., non-prunable) unreachable object which reaches the other. We'll call these objects "unreachable but reachable-from-recent". Here is how pack-objects handles `--cruft-expiration`: - Instead of adding all objects outside of the kept pack(s) into the packing list, only handle the ones whose mtime is within the grace period. - Construct a reachability traversal whose tips are the unreachable-but-recent objects. - Then, walk along that traversal, stopping if we reach an object in the kept pack. At each step along the traversal, we add the object we are visiting to the packing list. In the majority of these cases, any object we visit in this traversal will already be in our packing list. But we will sometimes encounter reachable-from-recent cruft objects, which we want to retain even if they aged out of the grace period. The most subtle point of this process is that we actually don't need to bother to update the rescued object's mtime. Even though we will write an .mtimes file with a value that is older than the expiration window, it will continue to survive cruft repacks so long as any objects which reach it haven't aged out. That is, a future repack will also exclude that object from the initial packing list, only to discover it later on when doing the reachability traversal. Finally, stopping early once an object is found in a kept pack is safe to do because the kept packs ordinarily represent which packs will survive after repacking. Assuming that it _isn't_ safe to halt a traversal early would mean that there is some ancestor object which is missing, which implies repository corruption (i.e., the complete set of reachable objects isn't present). Signed-off-by: Taylor Blau <me@ttaylorr.com> Signed-off-by: Junio C Hamano <gitster@pobox.com>
20 lines
520 B
C
20 lines
520 B
C
#ifndef REACHEABLE_H
|
|
#define REACHEABLE_H
|
|
|
|
struct progress;
|
|
struct rev_info;
|
|
struct object;
|
|
struct packed_git;
|
|
|
|
typedef void report_recent_object_fn(const struct object *, struct packed_git *,
|
|
off_t, time_t);
|
|
|
|
int add_unseen_recent_objects_to_traversal(struct rev_info *revs,
|
|
timestamp_t timestamp,
|
|
report_recent_object_fn cb,
|
|
int ignore_in_core_kept_packs);
|
|
void mark_reachable_objects(struct rev_info *revs, int mark_reflog,
|
|
timestamp_t mark_recent, struct progress *);
|
|
|
|
#endif
|