Files
Siddharth Shrimali 8bb2a3f454 builtin/repack: enumerate promisor blobs for --drop-filtered
Add enumeration logic for --drop-filtered. In --dry-run mode, print
the OIDs of locally-held promisor blobs that exceed the filter
threshold, as candidates for removal.

Reading from write_filtered_pack() cannot work for partial clones.
git repack routes promisor objects through a separate path:
repack_promisor_objects() repacks them first, and the main
pack-objects run uses --exclude-promisor-objects. By the time
write_filtered_pack() runs, the promisor blobs are already consumed by
the main pack. The filtered pack is always empty on a partial clone.

Instead, walk promisor objects directly via odb_for_each_object() with
ODB_FOR_EACH_OBJECT_PROMISOR_ONLY, collecting all promisor blobs into
an oidset. The blobs exceeding the filter threshold are then selected
using list_objects_filter__filter_oidset().

Every object enumerated this way is a promisor object, so it is
recoverable from the promisor remote in the same sense as the rest of a
partial clone, as long as the remote still has it. This holds without a
separate is_promisor_object() check. A future implementation can verify
availability against the remote directly once a client-side
remote-object-info query exists.

OBJECT_INFO_SKIP_FETCH_OBJECT is passed to every object info query so
enumeration never triggers a lazy fetch.

The enumeration collects candidates into a caller-provided oidset and
--dry-run prints them. Actually removing the objects, together with the
required promisor-remote verification, is written in a later commit.

Mentored-by: Christian Couder <christian.couder@gmail.com>
Mentored-by: Siddharth Asthana <siddharthasthana31@gmail.com>
Signed-off-by: Siddharth Shrimali <r.siddharth.shrimali@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
2026-08-13 13:34:49 -07:00

181 lines
5.4 KiB
C

#ifndef REPACK_H
#define REPACK_H
#include "list-objects-filter-options.h"
#include "string-list.h"
#include "oidset.h"
struct pack_objects_args {
char *window;
char *window_memory;
char *depth;
char *threads;
unsigned long max_pack_size;
int no_reuse_delta;
int no_reuse_object;
int quiet;
int local;
int name_hash_version;
int path_walk;
int delta_base_offset;
int pack_kept_objects;
struct list_objects_filter_options filter_options;
};
#define PACK_OBJECTS_ARGS_INIT { \
.delta_base_offset = 1, \
.pack_kept_objects = -1, \
}
struct child_process;
void prepare_pack_objects(struct child_process *cmd,
const struct pack_objects_args *args,
const char *out);
void pack_objects_args_release(struct pack_objects_args *args);
void repack_remove_redundant_pack(struct repository *repo, const char *dir_name,
const char *base_name,
bool wrote_incremental_midx);
struct write_pack_opts {
struct pack_objects_args *po_args;
const char *destination;
const char *packdir;
const char *packtmp;
};
const char *write_pack_opts_pack_prefix(const struct write_pack_opts *opts);
bool write_pack_opts_is_local(const struct write_pack_opts *opts);
int finish_pack_objects_cmd(const struct git_hash_algo *algop,
const struct write_pack_opts *opts,
struct child_process *cmd,
struct string_list *names);
struct repository;
struct packed_git;
struct existing_packs {
struct repository *repo;
struct odb_source *source;
struct string_list kept_packs;
struct string_list non_kept_packs;
struct string_list cruft_packs;
struct string_list midx_packs;
};
#define EXISTING_PACKS_INIT { \
.kept_packs = STRING_LIST_INIT_DUP, \
.non_kept_packs = STRING_LIST_INIT_DUP, \
.cruft_packs = STRING_LIST_INIT_DUP, \
}
/*
* Adds all packs hex strings (pack-$HASH) to either packs->non_kept
* or packs->kept based on whether each pack has a corresponding
* .keep file or not. Packs without a .keep file are not to be kept
* if we are going to pack everything into one file.
*/
void existing_packs_collect(struct existing_packs *existing,
const struct string_list *extra_keep);
int existing_packs_has_non_kept(const struct existing_packs *existing);
int existing_pack_is_marked_for_deletion(struct string_list_item *item);
void existing_packs_retain_cruft(struct existing_packs *existing,
struct packed_git *cruft);
void existing_packs_mark_for_deletion(struct existing_packs *existing,
struct string_list *names);
void existing_packs_retain_midx_packs(struct existing_packs *existing);
void existing_packs_remove_redundant(struct existing_packs *existing,
const char *packdir,
bool wrote_incremental_midx);
void existing_packs_release(struct existing_packs *existing);
struct generated_pack;
struct generated_pack *generated_pack_populate(const char *name,
const char *packtmp);
int generated_pack_has_ext(const struct generated_pack *pack, const char *ext);
void generated_pack_install(struct generated_pack *pack, const char *name,
const char *packdir, const char *packtmp);
void repack_promisor_objects(struct repository *repo,
const struct pack_objects_args *args,
struct string_list *names, const char *packtmp,
const struct oidset *to_drop);
struct pack_geometry {
struct packed_git **pack;
uint32_t pack_nr, pack_alloc;
uint32_t split;
struct packed_git **promisor_pack;
uint32_t promisor_pack_nr, promisor_pack_alloc;
uint32_t promisor_split;
uint32_t midx_layer_threshold;
bool midx_layer_threshold_set;
bool midx_tip_rewritten;
int split_factor;
};
void pack_geometry_repack_promisors(struct repository *repo,
const struct pack_objects_args *args,
const struct pack_geometry *geometry,
struct string_list *names,
const char *packtmp);
void pack_geometry_init(struct pack_geometry *geometry,
struct existing_packs *existing,
const struct pack_objects_args *args);
void pack_geometry_split(struct pack_geometry *geometry);
struct packed_git *pack_geometry_preferred_pack(struct pack_geometry *geometry);
void pack_geometry_remove_redundant(struct pack_geometry *geometry,
struct string_list *names,
struct existing_packs *existing,
const char *packdir,
bool wrote_incremental_midx);
void pack_geometry_release(struct pack_geometry *geometry);
struct tempfile;
enum repack_write_midx_mode {
REPACK_WRITE_MIDX_NONE,
REPACK_WRITE_MIDX_DEFAULT,
REPACK_WRITE_MIDX_INCREMENTAL,
};
struct repack_write_midx_opts {
struct existing_packs *existing;
struct pack_geometry *geometry;
struct string_list *names;
const char *refs_snapshot;
const char *packdir;
int show_progress;
int write_bitmaps;
int midx_must_contain_cruft;
int midx_split_factor;
int midx_new_layer_threshold;
enum repack_write_midx_mode mode;
};
void midx_snapshot_refs(struct repository *repo, struct tempfile *f);
int repack_write_midx(struct repack_write_midx_opts *opts);
int write_filtered_pack(const struct write_pack_opts *opts,
struct existing_packs *existing,
struct string_list *names);
int enumerate_promisor_blobs(struct repository *repo,
const struct list_objects_filter_options *filter,
struct oidset *to_drop);
int write_cruft_pack(const struct write_pack_opts *opts,
const char *cruft_expiration,
unsigned long combine_cruft_below_size,
struct string_list *names,
struct existing_packs *existing);
#endif /* REPACK_H */