git/list[1] front-page[2] threads[3] people[4] search[5] about
 

[PATCH v5 00/15] packfile: carve out a new packfile store

From
Patrick Steinhardt <ps@pks.im>
Date
Sep 15, 2025, 08:54 UTC
Message-ID
<20250915-b4-pks-packfiles-store-v5-0-d6340350934f@pks.im>
In-Reply-To
<20250819-b4-pks-packfiles-store-v1-0-1660842e125a@pks.im>
Hi,

information about a object database's packfiles is currently distributed across two different structures:

  - `struct packed_git` contains the `next` pointer as well as the
    `mru_head`, both of which serve to store the list of packfiles.
  - `struct object_database` contains several fields that relate to the
    packfiles.

So we don't really have a central data structure that tracks our packfiles, and consequently responsibilities aren't always clear cut. A consequence for the upcoming pluggable object databases is that this makes it very hard to move management of packfiles from the object database level down into the object database source.

This patch series introduces a new `struct packfile_store`, which is about to become the single source of truth for managing packfiles, and carves out the packfile store subsystem.

This is the first step to make packfiles work with pluggable object databases. Next steps will be to:

  - Move the `struct packed_git::next` and `struct packed::mru_head`
    pointers into the packfile store so that `struct packed_git` only
    tracks a single packfile.
  - Push the `struct packfile_store` down one level so that it's not
    hosted by the object database anymore, but instead by the object
    database source.
Changes in v2:
  - Convert the `initialized` flag into a boolean.
  - Polish some commit messages.
  - Some smaller formatting changes to the layout of `struct
    object_database`.
  - Link to v1: https://lore.kernel.org/r/20250819-b4-pks-packfiles-store-v1-0-1660842e125a@pks.im
Changes in v3:
  - Rebased on top of master at 6ad8021821 (The fifth batch, 2025-08-29)
    with ps/object-store-midx-dedup-info at 13296ac909 (midx: compute
    paths via their source, 2025-08-11) merged into it. This fixes
    various conflicts with "seen". There's still two conflicts: a
    trivial one with jt/de-global-bulk-checkin. And a more complex one
    with tb/prepare-midx-pack-cleanup. I don't think it's necessary to
    really address the first one, but I'm unsure how to proceed with the
    second one given that the patch series still seems to be cooking.
  - Set `struct object_database::packfiles` to `NULL` after free'ing it.
  - Add a comment to explain the kept cache.
  - Fix a missing `obj_read_lock()` call.
  - Drop the commit that always adds packfiles to the MRU. I've moved
    this into a subsequent patch series.
  - Avoid some overly long lines by storing the pointer to the packfile
    store on the stack.
  - Point out the difference between `get_all_packs()` and
    `get_packed_git()`.
  - Link to v2: https://lore.kernel.org/r/20250821-b4-pks-packfiles-store-v2-0-d10623355e9f@pks.im
Changes in v4:
  - Small code style improvement as suggested by Junio.
  - Some commit message improvements as suggested by Karthik.
  - Link to v3: https://lore.kernel.org/r/20250902-b4-pks-packfiles-store-v3-0-6925278efeda@pks.im
Changes in v5:
  - Stop closing packfiles when freeing the packfile store.
  - Don't drop `get_packed_git()` for now. This will be done in a
    subsequent patch series.
  - Link to v4: https://lore.kernel.org/r/20250909-b4-pks-packfiles-store-v4-0-151c4ba3619f@pks.im
Thanks!
Patrick
---
Patrick Steinhardt (15):
      packfile: introduce a new `struct packfile_store`
      odb: move list of packfiles into `struct packfile_store`
      odb: move initialization bit into `struct packfile_store`
      odb: move packfile map into `struct packfile_store`
      odb: move MRU list of packfiles into `struct packfile_store`
      odb: move kept cache into `struct packfile_store`
      packfile: reorder functions to avoid function declaration
      packfile: refactor `prepare_packed_git()` to work on packfile store
      packfile: split up responsibilities of `reprepare_packed_git()`
      packfile: refactor `install_packed_git()` to work on packfile store
      packfile: introduce function to load and add packfiles
      packfile: move `get_multi_pack_index()` into "midx.c"
      packfile: refactor `get_packed_git()` to work on packfile store
      packfile: refactor `get_all_packs()` to work on packfile store
      packfile: refactor `get_packed_git_mru()` to work on packfile store
 builtin/backfill.c          |   2 +-
 builtin/cat-file.c          |   3 +-
 builtin/count-objects.c     |   3 +-
 builtin/fast-import.c       |  10 +-
 builtin/fsck.c              |  11 +-
 builtin/gc.c                |  14 ++-
 builtin/grep.c              |   2 +-
 builtin/index-pack.c        |  10 +-
 builtin/pack-objects.c      |  32 +++--
 builtin/pack-redundant.c    |   6 +-
 builtin/receive-pack.c      |   2 +-
 builtin/repack.c            |  11 +-
 bulk-checkin.c              |   2 +-
 connected.c                 |   5 +-
 fetch-pack.c                |   4 +-
 http-backend.c              |   5 +-
 http.c                      |   5 +-
 http.h                      |   2 +-
 midx.c                      |  29 ++---
 midx.h                      |   1 +
 object-name.c               |   6 +-
 odb.c                       |  40 +++++--
 odb.h                       |  34 ++----
 pack-bitmap.c               |   4 +-
 pack-objects.c              |   3 +-
 packfile.c                  | 283 ++++++++++++++++++++++++--------------------
 packfile.h                  | 125 ++++++++++++++++---
 server-info.c               |   3 +-
 t/helper/test-find-pack.c   |   2 +-
 t/helper/test-pack-mtimes.c |   2 +-
 transport-helper.c          |   2 +-
 31 files changed, 396 insertions(+), 267 deletions(-)
Range-diff versus v4:
 1:  b006e4f919 =  1:  6dbb423d97 packfile: introduce a new `struct packfile_store`
 2:  078a3aebf1 !  2:  1f402667fd odb: move list of packfiles into `struct packfile_store`
    @@ packfile.c: struct packfile_store *packfile_store_new(struct object_database *od
      
      void packfile_store_free(struct packfile_store *store)
      {
    -+	packfile_store_close(store);
    -+
     +	for (struct packed_git *p = store->packs, *next; p; p = next) {
     +		next = p->next;
     +		free(p);
     +	}
    -+
      	free(store);
      }
     +
 3:  8bbb9b5957 =  3:  b3bae09159 odb: move initialization bit into `struct packfile_store`
 4:  499826d25e !  4:  91d3c6016b odb: move packfile map into `struct packfile_store`
    @@ packfile.c: int parse_pack_header_option(const char *in, unsigned char *out, uns
      }
      
     @@ packfile.c: void packfile_store_free(struct packfile_store *store)
    + 		next = p->next;
      		free(p);
      	}
    - 
     +	hashmap_clear(&store->map);
      	free(store);
      }
 5:  54c02314ac =  5:  5aa029b482 odb: move MRU list of packfiles into `struct packfile_store`
 6:  7810d28c81 =  6:  d2f430f86f odb: move kept cache into `struct packfile_store`
 7:  c5cc67c267 =  7:  1f35516b99 packfile: reorder functions to avoid function declaration
 8:  012059000e =  8:  2c298068b5 packfile: refactor `prepare_packed_git()` to work on packfile store
 9:  f05aa1f700 =  9:  eece281f07 packfile: split up responsibilities of `reprepare_packed_git()`
10:  62ad7cfc0c = 10:  68d057c18c packfile: refactor `install_packed_git()` to work on packfile store
11:  ed795182ac = 11:  0700b475ce packfile: introduce function to load and add packfiles
12:  fc97ab562c = 12:  7d2e76e127 packfile: move `get_multi_pack_index()` into "midx.c"
13:  ececdd0a23 ! 13:  cea2433d84 packfile: remove `get_packed_git()`
    @@ Metadata
     Author: Patrick Steinhardt <ps@pks.im>
     
      ## Commit message ##
    -    packfile: remove `get_packed_git()`
    +    packfile: refactor `get_packed_git()` to work on packfile store
     
    -    We have two different functions to retrieve packfiles for a packfile
    -    store:
    -
    -      - `get_packed_git()` returns the list of packfiles after having called
    -        `prepare_packed_git()`.
    -
    -      - `get_all_packs()` calls `prepare_packed_git()`, as well, but also
    -        calls `prepare_midx_pack()` for each pack.
    -
    -    Based on the naming alone one might think that `get_all_packs()` would
    -    return more packs than `get_packed_git()`. But that's not the case: both
    -    functions end up returning the exact same list of packfiles. The real
    -    difference between those functions is that `get_all_packs()` also loads
    -    the info of whether or not a packfile is part of a multi-pack index.
    -
    -    Preparing this extra information also shouldn't be significantly more
    -    expensive:
    -
    -      - We have already loaded all packfiles via `prepare_packed_git_one()`.
    -        So given that multi-pack indices may only refer to packfiles in the
    -        same object directory we know that we already loaded each packfile.
    -
    -      - The multi-pack index was prepared via `packfile_store_prepare()`
    -        already, which calls `prepare_multi_pack_index_one()`.
    -
    -      - So all that remains to be done is to look up the index of the pack
    -        in its multi-pack index so that we can store that info in both the
    -        pack itself and the MIDX.
    -
    -    So it is somewhat confusing to readers that one of these two functions
    -    claims to load "all" packfiles while the other one doesn't, even though
    -    the ultimate difference is way more nuanced.
    -
    -    Convert all of these sites to use `get_all_packs()` instead and remove
    -    `get_packed_git()`. There doesn't seem to be a good reason to discern
    -    these two functions.
    +    The `get_packed_git()` function prepares the packfile store and then
    +    returns its packfiles. Refactor it to accept a packfile store instead of
    +    a repository to clarify its scope.
     
         Signed-off-by: Patrick Steinhardt <ps@pks.im>
     
    @@ builtin/gc.c: static int incremental_repack_auto_condition(struct gc_config *cfg
      		return 1;
      
     -	for (p = get_packed_git(the_repository);
    -+	for (p = get_all_packs(the_repository);
    ++	for (p = packfile_store_get_packs(the_repository->objects->packfiles);
      	     count < incremental_repack_auto_limit && p;
      	     p = p->next) {
      		if (!p->multi_pack_index)
    @@ builtin/grep.c: int cmd_grep(int argc,
      			repo_read_gitmodules(the_repository, 1);
      		if (startup_info->have_repository)
     -			(void)get_packed_git(the_repository);
    -+			packfile_store_prepare(the_repository->objects->packfiles);
    ++			(void)packfile_store_get_packs(the_repository->objects->packfiles);
      
      		start_threads(&opt);
      	} else {
    @@ object-name.c: static void find_short_packed_object(struct disambiguate_state *d
      	}
      
     -	for (p = get_packed_git(ds->repo); p && !ds->ambiguous;
    -+	for (p = get_all_packs(ds->repo); p && !ds->ambiguous;
    ++	for (p = packfile_store_get_packs(ds->repo->objects->packfiles); p && !ds->ambiguous;
      	     p = p->next)
      		unique_in_pack(p, ds);
      }
    @@ object-name.c: static void find_abbrev_len_packed(struct min_abbrev_data *mad)
      	}
      
     -	for (p = get_packed_git(mad->repo); p; p = p->next)
    -+	for (p = get_all_packs(mad->repo); p; p = p->next)
    ++	for (p = packfile_store_get_packs(mad->repo->objects->packfiles); p; p = p->next)
      		find_abbrev_len_for_pack(p, mad);
      }
      
    @@ packfile.c: void packfile_store_reprepare(struct packfile_store *store)
      }
      
     -struct packed_git *get_packed_git(struct repository *r)
    --{
    ++struct packed_git *packfile_store_get_packs(struct packfile_store *store)
    + {
     -	packfile_store_prepare(r->objects->packfiles);
     -	return r->objects->packfiles->packs;
    --}
    --
    ++	packfile_store_prepare(store);
    ++	return store->packs;
    + }
    + 
      struct packed_git *get_all_packs(struct repository *r)
    - {
    - 	packfile_store_prepare(r->objects->packfiles);
     
      ## packfile.h ##
    +@@ packfile.h: void packfile_store_reprepare(struct packfile_store *store);
    + void packfile_store_add_pack(struct packfile_store *store,
    + 			     struct packed_git *pack);
    + 
    ++/*
    ++ * Get packs managed by the given store. Does not load the MIDX or any packs
    ++ * referenced by it.
    ++ */
    ++struct packed_git *packfile_store_get_packs(struct packfile_store *store);
    ++
    + /*
    +  * Open the packfile and add it to the store if it isn't yet known. Returns
    +  * either the newly opened packfile or the preexisting packfile. Returns a
     @@ packfile.h: int for_each_packed_object(struct repository *repo, each_packed_object_fn cb,
      #define PACKDIR_FILE_GARBAGE 4
      extern void (*report_garbage)(unsigned seen_bits, const char *path);
14:  ed7a0d5457 ! 14:  8d5296bbbe packfile: refactor `get_all_packs()` to work on packfile store
    @@ builtin/cat-file.c: static void batch_each_object(struct batch_options *opt,
      		struct packed_git *pack;
      
     -		for (pack = get_all_packs(the_repository); pack; pack = pack->next) {
    -+		for (pack = packfile_store_get_packs(packs); pack; pack = pack->next) {
    ++		for (pack = packfile_store_get_all_packs(packs); pack; pack = pack->next) {
      			if (bitmap_index_contains_pack(bitmap, pack) ||
      			    open_pack_index(pack))
      				continue;
    @@ builtin/count-objects.c: int cmd_count_objects(int argc,
      		struct strbuf garbage_buf = STRBUF_INIT;
      
     -		for (p = get_all_packs(the_repository); p; p = p->next) {
    -+		for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++		for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      			if (!p->pack_local)
      				continue;
      			if (open_pack_index(p))
    @@ builtin/fast-import.c: static int store_object(
      		duplicate_count_by_type[type]++;
      		return 1;
     -	} else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
    -+	} else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
    ++	} else if (find_oid_pack(&oid, packfile_store_get_all_packs(packs))) {
      		e->type = type;
      		e->pack_id = MAX_PACK_ID;
      		e->idx.offset = 1; /* just not zero! */
    @@ builtin/fast-import.c: static void stream_blob(uintmax_t len, struct object_id *
      		truncate_pack(&checkpoint);
      
     -	} else if (find_oid_pack(&oid, get_all_packs(the_repository))) {
    -+	} else if (find_oid_pack(&oid, packfile_store_get_packs(packs))) {
    ++	} else if (find_oid_pack(&oid, packfile_store_get_all_packs(packs))) {
      		e->type = OBJ_BLOB;
      		e->pack_id = MAX_PACK_ID;
      		e->idx.offset = 1; /* just not zero! */
    @@ builtin/fsck.c: static int mark_packed_for_connectivity(const struct object_id *
      
      	if (show_progress) {
     -		for (struct packed_git *p = get_all_packs(r); p; p = p->next)
    -+		for (struct packed_git *p = packfile_store_get_packs(packs); p; p = p->next)
    ++		for (struct packed_git *p = packfile_store_get_all_packs(packs); p; p = p->next)
      			pack_count++;
      		progress = start_delayed_progress(the_repository,
      						  "Verifying reverse pack-indexes", pack_count);
    @@ builtin/fsck.c: static int mark_packed_for_connectivity(const struct object_id *
      	}
      
     -	for (struct packed_git *p = get_all_packs(r); p; p = p->next) {
    -+	for (struct packed_git *p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (struct packed_git *p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		int load_error = load_pack_revindex_from_disk(p);
      
      		if (load_error < 0) {
    @@ builtin/fsck.c: int cmd_fsck(int argc,
      
      			if (show_progress) {
     -				for (p = get_all_packs(the_repository); p;
    -+				for (p = packfile_store_get_packs(packs); p;
    ++				for (p = packfile_store_get_all_packs(packs); p;
      				     p = p->next) {
      					if (open_pack_index(p))
      						continue;
    @@ builtin/fsck.c: int cmd_fsck(int argc,
      							  _("Checking objects"), total);
      			}
     -			for (p = get_all_packs(the_repository); p;
    -+			for (p = packfile_store_get_packs(packs); p;
    ++			for (p = packfile_store_get_all_packs(packs); p;
      			     p = p->next) {
      				/* verify gives error messages itself */
      				if (verify_pack(the_repository,
    @@ builtin/gc.c: static int too_many_loose_objects(struct gc_config *cfg)
      	struct packed_git *p, *base = NULL;
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packfiles); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packfiles); p; p = p->next) {
      		if (!p->pack_local || p->is_cruft)
      			continue;
      		if (limit) {
    @@ builtin/gc.c: static struct packed_git *find_base_packs(struct string_list *pack
      		return 0;
      
     -	for (cnt = 0, p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (cnt = 0, p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (cnt = 0, p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (!p->pack_local)
      			continue;
      		if (p->pack_keep)
    -@@ builtin/gc.c: static int incremental_repack_auto_condition(struct gc_config *cfg UNUSED)
    - 	if (incremental_repack_auto_limit < 0)
    - 		return 1;
    - 
    --	for (p = get_all_packs(the_repository);
    -+	for (p = packfile_store_get_packs(the_repository->objects->packfiles);
    - 	     count < incremental_repack_auto_limit && p;
    - 	     p = p->next) {
    - 		if (!p->multi_pack_index)
     @@ builtin/gc.c: static off_t get_auto_pack_size(void)
      	struct repository *r = the_repository;
      
      	odb_reprepare(r->objects);
     -	for (p = get_all_packs(r); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(r->objects->packfiles); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(r->objects->packfiles); p; p = p->next) {
      		if (p->pack_size > max_size) {
      			second_largest_size = max_size;
      			max_size = p->pack_size;
    @@ builtin/pack-objects.c: static void read_packs_list_from_stdin(struct rev_info *
      	string_list_remove_duplicates(&exclude_packs, 0);
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		const char *pack_name = pack_basename(p);
      
      		if ((item = string_list_lookup(&include_packs, pack_name)))
    @@ builtin/pack-objects.c: static void enumerate_and_traverse_cruft_objects(struct
      	 * unknown packs do not halt the reachability traversal early.
      	 */
     -	for (p = get_all_packs(the_repository); p; p = p->next)
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next)
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next)
      		p->pack_keep_in_core = 0;
      	mark_pack_kept_in_core(fresh_packs, 1);
      
    @@ builtin/pack-objects.c: static void read_cruft_objects(void)
      	string_list_sort(&fresh_packs);
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		const char *pack_name = pack_basename(p);
      		struct string_list_item *item;
      
    @@ builtin/pack-objects.c: static void add_unreachable_loose_objects(struct rev_inf
      
      	p = (last_found != (void *)1) ? last_found :
     -					get_all_packs(the_repository);
    -+					packfile_store_get_packs(packs);
    ++					packfile_store_get_all_packs(packs);
      
      	while (p) {
      		if ((!p->pack_local || p->pack_keep ||
    @@ builtin/pack-objects.c: static int has_sha1_pack_kept_or_nonlocal(const struct o
      		}
      		if (p == last_found)
     -			p = get_all_packs(the_repository);
    -+			p = packfile_store_get_packs(packs);
    ++			p = packfile_store_get_all_packs(packs);
      		else
      			p = p->next;
      		if (p == last_found)
    @@ builtin/pack-objects.c: static int loosened_object_can_be_discarded(const struct
      	struct object_id oid;
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (!p->pack_local || p->pack_keep || p->pack_keep_in_core)
      			continue;
      
    @@ builtin/pack-objects.c: static void get_object_list(struct rev_info *revs, int a
      		return;
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		const char *name = basename(p->pack_name);
      		int i;
      
    @@ builtin/pack-objects.c: int cmd_pack_objects(int argc,
      		struct packed_git *p;
     -		for (p = get_all_packs(the_repository); p; p = p->next)
     +
    -+		for (p = packfile_store_get_packs(packs); p; p = p->next)
    ++		for (p = packfile_store_get_all_packs(packs); p; p = p->next)
      			if (p->pack_local && p->pack_keep)
      				break;
      		if (!p) /* no keep-able packs found */
    @@ builtin/pack-objects.c: int cmd_pack_objects(int argc,
      		struct packed_git *p;
     -		for (p = get_all_packs(the_repository); p; p = p->next) {
     +
    -+		for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++		for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      			if (!p->pack_local) {
      				have_non_local_packs = 1;
      				break;
    @@ builtin/pack-redundant.c: static struct pack_list * add_pack(struct packed_git *
      {
     -	struct packed_git *p = get_all_packs(the_repository);
     +	struct packfile_store *packs = the_repository->objects->packfiles;
    -+	struct packed_git *p = packfile_store_get_packs(packs);
    ++	struct packed_git *p = packfile_store_get_all_packs(packs);
      
      	if (strlen(filename) < 40)
      		die("Bad pack filename: %s", filename);
    @@ builtin/pack-redundant.c: static struct pack_list * add_pack_file(const char *fi
      {
     -	struct packed_git *p = get_all_packs(the_repository);
     +	struct packfile_store *packs = the_repository->objects->packfiles;
    -+	struct packed_git *p = packfile_store_get_packs(packs);
    ++	struct packed_git *p = packfile_store_get_all_packs(packs);
      
      	while (p) {
      		add_pack(p);
    @@ builtin/repack.c: static void existing_packs_release(struct existing_packs *exis
      	struct strbuf buf = STRBUF_INIT;
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		int i;
      		const char *base;
      
    @@ builtin/repack.c: static void init_pack_geometry(struct pack_geometry *geometry,
      	struct strbuf buf = STRBUF_INIT;
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (args->local && !p->pack_local)
      			/*
      			 * When asked to only repack local packfiles we skip
    @@ builtin/repack.c: static int write_filtered_pack(const struct pack_objects_args
      	size_t i;
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (!(p->is_cruft && p->pack_local))
      			continue;
      
    @@ connected.c: int check_connected(oid_iterate_fn fn, void *cb_data,
      			struct packed_git *p;
      
     -			for (p = get_all_packs(the_repository); p; p = p->next) {
    -+			for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++			for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      				if (!p->pack_promisor)
      					continue;
      				if (find_pack_entry_one(oid, p))
    @@ http-backend.c: static void get_head(struct strbuf *hdr, char *arg UNUSED)
      
      	select_getanyfile(hdr);
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (p->pack_local)
      			cnt++;
      	}
      
      	strbuf_grow(&buf, cnt * 53 + 2);
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (p->pack_local)
      			strbuf_addf(&buf, "P %s\n", p->pack_name + objdirlen + 6);
      	}
    @@ http.c: static int fetch_and_setup_pack_index(struct packed_git **packs_head,
      	 * even add it to list; we already have all of its objects.
      	 */
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		if (hasheq(p->hash, sha1, the_repository->hash_algo))
      			return 0;
      	}
     
    - ## object-name.c ##
    -@@ object-name.c: static void find_short_packed_object(struct disambiguate_state *ds)
    - 			unique_in_midx(m, ds);
    - 	}
    - 
    --	for (p = get_all_packs(ds->repo); p && !ds->ambiguous;
    -+	for (p = packfile_store_get_packs(ds->repo->objects->packfiles); p && !ds->ambiguous;
    - 	     p = p->next)
    - 		unique_in_pack(p, ds);
    - }
    -@@ object-name.c: static void find_abbrev_len_packed(struct min_abbrev_data *mad)
    - 			find_abbrev_len_for_midx(m, mad);
    - 	}
    - 
    --	for (p = get_all_packs(mad->repo); p; p = p->next)
    -+	for (p = packfile_store_get_packs(mad->repo->objects->packfiles); p; p = p->next)
    - 		find_abbrev_len_for_pack(p, mad);
    - }
    - 
    -
      ## pack-bitmap.c ##
     @@ pack-bitmap.c: static int open_pack_bitmap(struct repository *r,
      	struct packed_git *p;
      	int ret = -1;
      
     -	for (p = get_all_packs(r); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(r->objects->packfiles); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(r->objects->packfiles); p; p = p->next) {
      		if (open_pack_bitmap_1(bitmap_git, p) == 0) {
      			ret = 0;
      			/*
    @@ pack-bitmap.c: int verify_bitmap_files(struct repository *r)
      	}
      
     -	for (struct packed_git *p = get_all_packs(r);
    -+	for (struct packed_git *p = packfile_store_get_packs(r->objects->packfiles);
    ++	for (struct packed_git *p = packfile_store_get_all_packs(r->objects->packfiles);
      	     p; p = p->next) {
      		char *pack_bitmap_name = pack_bitmap_filename(p);
      		res |= verify_bitmap_file(r->hash_algo, pack_bitmap_name);
    @@ pack-objects.c: static void prepare_in_pack_by_idx(struct packing_data *pdata)
      	 */
      	mapping[cnt++] = NULL;
     -	for (p = get_all_packs(pdata->repo); p; p = p->next, cnt++) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next, cnt++) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next, cnt++) {
      		if (cnt == nr) {
      			free(mapping);
      			return;
     
      ## packfile.c ##
    -@@ packfile.c: void packfile_store_reprepare(struct packfile_store *store)
    - 	packfile_store_prepare(store);
    +@@ packfile.c: struct packed_git *packfile_store_get_packs(struct packfile_store *store)
    + 	return store->packs;
      }
      
     -struct packed_git *get_all_packs(struct repository *r)
    -+struct packed_git *packfile_store_get_packs(struct packfile_store *store)
    ++struct packed_git *packfile_store_get_all_packs(struct packfile_store *store)
      {
     -	packfile_store_prepare(r->objects->packfiles);
     +	packfile_store_prepare(store);
    @@ packfile.c: struct packed_git **kept_pack_cache(struct repository *r, unsigned f
      		 * the non-kept version.
      		 */
     -		for (p = get_all_packs(r); p; p = p->next) {
    -+		for (p = packfile_store_get_packs(r->objects->packfiles); p; p = p->next) {
    ++		for (p = packfile_store_get_all_packs(r->objects->packfiles); p; p = p->next) {
      			if ((p->pack_keep && (flags & ON_DISK_KEEP_PACKS)) ||
      			    (p->pack_keep_in_core && (flags & IN_CORE_KEEP_PACKS))) {
      				ALLOC_GROW(packs, nr + 1, alloc);
    @@ packfile.c: int for_each_packed_object(struct repository *repo, each_packed_obje
      	int pack_errors = 0;
      
     -	for (p = get_all_packs(repo); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(repo->objects->packfiles); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(repo->objects->packfiles); p; p = p->next) {
      		if ((flags & FOR_EACH_OBJECT_LOCAL_ONLY) && !p->pack_local)
      			continue;
      		if ((flags & FOR_EACH_OBJECT_PROMISOR_ONLY) &&
     
      ## packfile.h ##
    -@@ packfile.h: void packfile_store_reprepare(struct packfile_store *store);
    - void packfile_store_add_pack(struct packfile_store *store,
    - 			     struct packed_git *pack);
    +@@ packfile.h: void packfile_store_add_pack(struct packfile_store *store,
    +  */
    + struct packed_git *packfile_store_get_packs(struct packfile_store *store);
      
     +/*
     + * Get all packs managed by the given store, including packfiles that are
     + * referenced by multi-pack indices.
     + */
    -+struct packed_git *packfile_store_get_packs(struct packfile_store *store);
    ++struct packed_git *packfile_store_get_all_packs(struct packfile_store *store);
     +
      /*
       * Open the packfile and add it to the store if it isn't yet known. Returns
    @@ server-info.c: static int compare_info(const void *a_, const void *b_)
      	size_t alloc = 0;
      
     -	for (p = get_all_packs(r); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(packs); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(packs); p; p = p->next) {
      		/* we ignore things on alternate path since they are
      		 * not available to the pullers in general.
      		 */
    @@ t/helper/test-find-pack.c: int cmd__find_pack(int argc, const char **argv)
      		die("cannot parse %s as an object name", argv[0]);
      
     -	for (p = get_all_packs(the_repository); p; p = p->next)
    -+	for (p = packfile_store_get_packs(the_repository->objects->packfiles); p; p = p->next)
    ++	for (p = packfile_store_get_all_packs(the_repository->objects->packfiles); p; p = p->next)
      		if (find_pack_entry_one(&oid, p)) {
      			printf("%s\n", p->pack_name);
      			actual_count++;
    @@ t/helper/test-pack-mtimes.c: int cmd__pack_mtimes(int argc, const char **argv)
      		usage(pack_mtimes_usage);
      
     -	for (p = get_all_packs(the_repository); p; p = p->next) {
    -+	for (p = packfile_store_get_packs(the_repository->objects->packfiles); p; p = p->next) {
    ++	for (p = packfile_store_get_all_packs(the_repository->objects->packfiles); p; p = p->next) {
      		strbuf_addstr(&buf, basename(p->pack_name));
      		strbuf_strip_suffix(&buf, ".pack");
      		strbuf_addstr(&buf, ".mtimes");
15:  6af591f605 ! 15:  444f7f3b3f packfile: refactor `get_packed_git_mru()` to work on packfile store
    @@ builtin/pack-objects.c: static int want_object_in_pack_mtime(const struct object
      	}
     
      ## packfile.c ##
    -@@ packfile.c: struct packed_git *packfile_store_get_packs(struct packfile_store *store)
    +@@ packfile.c: struct packed_git *packfile_store_get_all_packs(struct packfile_store *store)
      	return store->packs;
      }
      
    @@ packfile.c: struct packed_git *packfile_store_get_packs(struct packfile_store *s
      /*
     
      ## packfile.h ##
    -@@ packfile.h: void packfile_store_add_pack(struct packfile_store *store,
    +@@ packfile.h: struct packed_git *packfile_store_get_packs(struct packfile_store *store);
       */
    - struct packed_git *packfile_store_get_packs(struct packfile_store *store);
    + struct packed_git *packfile_store_get_all_packs(struct packfile_store *store);
      
     +/*
     + * Get all packs in most-recently-used order.

--- base-commit: 337c7a0bbcf228ce11c87d066ecee352b3e52467 change-id: 20250806-b4-pks-packfiles-store-a44a608ca396

Previous: Patrick SteinhardtNext: Patrick Steinhardt
Message 137 of 181 in “packfile: carve out a new packfile store”
  1. 00/16 packfile: carve out a new packfile storePatrick Steinhardt, Aug 19, 2025
  2. 01/16 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  3. Karthik NayakAug 19, 2025
  4. Patrick SteinhardtAug 20, 2025
  5. Junio C HamanoAug 19, 2025
  6. Patrick SteinhardtAug 20, 2025
  7. 02/16 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  8. 03/16 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  9. Karthik NayakAug 19, 2025
  10. Junio C HamanoAug 19, 2025
  11. Karthik NayakAug 20, 2025
  12. Junio C HamanoAug 22, 2025
  13. Documentation: note styling for bit fieldsKarthik Nayak, Aug 26, 2025
  14. Patrick SteinhardtAug 20, 2025
  15. Junio C HamanoAug 20, 2025
  16. 04/16 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  17. 05/16 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  18. Karthik NayakAug 20, 2025
  19. Jeff KingAug 20, 2025
  20. Patrick SteinhardtAug 21, 2025
  21. 06/16 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Aug 19, 2025
  22. Junio C HamanoAug 19, 2025
  23. Patrick SteinhardtAug 20, 2025
  24. 07/16 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Aug 19, 2025
  25. Junio C HamanoAug 19, 2025
  26. 08/16 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  27. 09/16 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Aug 19, 2025
  28. Karthik NayakAug 20, 2025
  29. 10/16 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  30. 11/16 packfile: always add packfiles to MRU when adding a packPatrick Steinhardt, Aug 19, 2025
  31. Karthik NayakAug 20, 2025
  32. 12/16 packfile: introduce function to load and add packfilesPatrick Steinhardt, Aug 19, 2025
  33. Karthik NayakAug 20, 2025
  34. Patrick SteinhardtAug 21, 2025
  35. 13/16 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Aug 19, 2025
  36. 14/16 packfile: remove `get_packed_git()`Patrick Steinhardt, Aug 19, 2025
  37. Karthik NayakAug 20, 2025
  38. Patrick SteinhardtAug 21, 2025
  39. Karthik NayakAug 20, 2025
  40. 15/16 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  41. Karthik NayakAug 20, 2025
  42. Patrick SteinhardtAug 21, 2025
  43. 16/16 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Aug 19, 2025
  44. Junio C HamanoAug 19, 2025
  45. Karthik NayakAug 20, 2025
  46. 00/16 packfile: carve out a new packfile storePatrick Steinhardt, Aug 21, 2025
  47. 01/16 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  48. 02/16 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  49. Taylor BlauAug 25, 2025
  50. Patrick SteinhardtSep 2, 2025
  51. Taylor BlauSep 2, 2025
  52. Junio C HamanoSep 2, 2025
  53. Patrick SteinhardtSep 3, 2025
  54. Taylor BlauSep 11, 2025
  55. Patrick SteinhardtSep 15, 2025
  56. 03/16 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  57. Taylor BlauAug 26, 2025
  58. 04/16 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  59. Taylor BlauAug 26, 2025
  60. 05/16 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  61. 06/16 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Aug 21, 2025
  62. Taylor BlauAug 26, 2025
  63. Patrick SteinhardtSep 2, 2025
  64. 07/16 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Aug 21, 2025
  65. Taylor BlauAug 26, 2025
  66. 08/16 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  67. Taylor BlauAug 26, 2025
  68. 09/16 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Aug 21, 2025
  69. Taylor BlauAug 26, 2025
  70. Patrick SteinhardtSep 2, 2025
  71. 10/16 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  72. Taylor BlauAug 26, 2025
  73. Patrick SteinhardtSep 2, 2025
  74. 11/16 packfile: always add packfiles to MRU when adding a packPatrick Steinhardt, Aug 21, 2025
  75. Taylor BlauAug 27, 2025
  76. Patrick SteinhardtSep 2, 2025
  77. 12/16 packfile: introduce function to load and add packfilesPatrick Steinhardt, Aug 21, 2025
  78. Taylor BlauAug 27, 2025
  79. 13/16 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Aug 21, 2025
  80. Taylor BlauAug 27, 2025
  81. 14/16 packfile: remove `get_packed_git()`Patrick Steinhardt, Aug 21, 2025
  82. Taylor BlauAug 27, 2025
  83. Patrick SteinhardtSep 2, 2025
  84. Taylor BlauSep 11, 2025
  85. Patrick SteinhardtSep 15, 2025
  86. 15/16 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  87. Taylor BlauAug 27, 2025
  88. Patrick SteinhardtSep 2, 2025
  89. Taylor BlauSep 11, 2025
  90. Patrick SteinhardtSep 15, 2025
  91. 16/16 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Aug 21, 2025
  92. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 2, 2025
  93. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  94. Karthik NayakSep 9, 2025
  95. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  96. Karthik NayakSep 9, 2025
  97. Patrick SteinhardtSep 9, 2025
  98. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  99. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  100. Karthik NayakSep 9, 2025
  101. Patrick SteinhardtSep 9, 2025
  102. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  103. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 2, 2025
  104. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 2, 2025
  105. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  106. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 2, 2025
  107. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  108. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 2, 2025
  109. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 2, 2025
  110. 13/15 packfile: remove `get_packed_git()`Patrick Steinhardt, Sep 2, 2025
  111. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  112. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 2, 2025
  113. Junio C HamanoSep 2, 2025
  114. Taylor BlauSep 11, 2025
  115. Karthik NayakSep 9, 2025
  116. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 9, 2025
  117. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  118. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  119. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  120. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  121. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  122. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 9, 2025
  123. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 9, 2025
  124. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  125. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 9, 2025
  126. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  127. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 9, 2025
  128. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 9, 2025
  129. 13/15 packfile: remove `get_packed_git()`Patrick Steinhardt, Sep 9, 2025
  130. Taylor BlauSep 11, 2025
  131. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  132. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 9, 2025
  133. Karthik NayakSep 10, 2025
  134. Taylor BlauSep 11, 2025
  135. Taylor BlauSep 11, 2025
  136. Patrick SteinhardtSep 15, 2025
  137. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 15, 2025
  138. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  139. Justin ToblerSep 17, 2025
  140. Patrick SteinhardtSep 23, 2025
  141. Justin ToblerSep 24, 2025
  142. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  143. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  144. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  145. Justin ToblerSep 17, 2025
  146. Patrick SteinhardtSep 23, 2025
  147. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  148. Justin ToblerSep 17, 2025
  149. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 15, 2025
  150. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 15, 2025
  151. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  152. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 15, 2025
  153. Justin ToblerSep 17, 2025
  154. Patrick SteinhardtSep 23, 2025
  155. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  156. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 15, 2025
  157. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 15, 2025
  158. 13/15 packfile: refactor `get_packed_git()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  159. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  160. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 15, 2025
  161. 00/15 packfile: carve out a new packfile storePatrick Steinhardt, Sep 23, 2025
  162. 01/15 packfile: introduce a new `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  163. 02/15 odb: move list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  164. 03/15 odb: move initialization bit into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  165. 04/15 odb: move packfile map into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  166. 05/15 odb: move MRU list of packfiles into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  167. 06/15 odb: move kept cache into `struct packfile_store`Patrick Steinhardt, Sep 23, 2025
  168. 07/15 packfile: reorder functions to avoid function declarationPatrick Steinhardt, Sep 23, 2025
  169. 08/15 packfile: refactor `prepare_packed_git()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  170. 09/15 packfile: split up responsibilities of `reprepare_packed_git()`Patrick Steinhardt, Sep 23, 2025
  171. 10/15 packfile: refactor `install_packed_git()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  172. 11/15 packfile: introduce function to load and add packfilesPatrick Steinhardt, Sep 23, 2025
  173. 12/15 packfile: move `get_multi_pack_index()` into "midx.c"Patrick Steinhardt, Sep 23, 2025
  174. 13/15 packfile: refactor `get_packed_git()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  175. 14/15 packfile: refactor `get_all_packs()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  176. 15/15 packfile: refactor `get_packed_git_mru()` to work on packfile storePatrick Steinhardt, Sep 23, 2025
  177. Justin ToblerSep 24, 2025
  178. Junio C HamanoSep 25, 2025
  179. Patrick SteinhardtSep 26, 2025
  180. Taylor BlauSep 28, 2025
  181. Patrick SteinhardtSep 29, 2025

Read the whole thread, see it on lore, or plain text.

$ cat FOOTERMessages come from the public archive at lore.kernel.org/git, fetched every hour. The front page is chosen and written each morning by an AI editor and can be wrong; the threads themselves are the record. About and API. For agents: an MCP server at https://gitlist.dev/mcp, and any thread, story or person page as Markdown by adding .md to its URL (or sending Accept: text/markdown). Details in /llms.txt.