* Performance regression in connectivity check during receive-pack (git 2.54)
@ 2026-07-21 3:17 Wolfgang Kritzinger
2026-07-21 3:57 ` Jeff King
0 siblings, 1 reply; 8+ messages in thread
From: Wolfgang Kritzinger @ 2026-07-21 3:17 UTC (permalink / raw)
To: git
Hi!
I'm a developer working on the on-premise version of Bitbucket at
Atlassian.
We noticed pushes to Bitbucket got much slower after upgrading Git
on the server side from 2.50 to 2.54. I traced the slow part to
the connectivity check that receive-pack runs:
git rev-list --objects --stdin --not --exclude-hidden=receive --all \
--quiet --alternate-refs --progress=Checking connectivity
`strace` shows that after a push, 2.54 does a failing open() of
of numerous loose objects -- once in the quarantine (incoming)
directory and once in the main object store -- before finding it
in a pack:
openat(".../objects/tmp_objdir-incoming-XXXX/ed/58..", O_RDONLY) = ENOENT
openat(".../objects/ed/58..", O_RDONLY) = ENOENT
2.50 does not do this. In most customer deployments of Bitbucket,
the Git data lives on an NFS share. The extra latency on NFS makes
this process of checking for non-existent loose objects take too
long, the push essentially hangs at the "Checking connectivity" step.
I believe this new behavior was introduced in the recent object
database rework. After using bisect, I belive the problem can be
traced back to commit 8384cbcb4c.
I don't know the codebase well, but from what I can see is that
the order in which objects are looked up in object databases
changed.
Assuming there are two object databases configured (Main repo,
and the quarantine directory, for example), the lookup order used
to be:
1. _quarantine dir_ packs
2. _main dir_ packs
3. _quarantine dir_ loose objects
4. _main dir_ loose objects
With Git 2.54, the order appears to have changed to:
1. _quarantine dir_ packs
2. _quarantine dir_ loose objects
3. _main dir_ packs
4. _main dir_ loose objects
In my testing, within a well-packed repo, Git 2.50 actually never
performed a loose object lookup.
The current design seems to iterate over the configured object
databases and perform a pack and loose object lookup for each.
Is there a way to avoid these costly loose object lookups?
^ permalink raw reply [flat|nested] 8+ messages in thread* Re: Performance regression in connectivity check during receive-pack (git 2.54) 2026-07-21 3:17 Performance regression in connectivity check during receive-pack (git 2.54) Wolfgang Kritzinger @ 2026-07-21 3:57 ` Jeff King 2026-07-21 5:05 ` Taylor Blau 2026-07-21 14:40 ` Junio C Hamano 0 siblings, 2 replies; 8+ messages in thread From: Jeff King @ 2026-07-21 3:57 UTC (permalink / raw) To: Wolfgang Kritzinger; +Cc: Patrick Steinhardt, git On Tue, Jul 21, 2026 at 03:17:23PM +1200, Wolfgang Kritzinger wrote: > `strace` shows that after a push, 2.54 does a failing open() of > of numerous loose objects -- once in the quarantine (incoming) > directory and once in the main object store -- before finding it > in a pack: > > openat(".../objects/tmp_objdir-incoming-XXXX/ed/58..", O_RDONLY) = ENOENT > openat(".../objects/ed/58..", O_RDONLY) = ENOENT Interesting. Here's a smaller reproduction recipe that shows the issue: # clone of git.git, or any other non-trivial repo; it should be mostly # packed src=/path/to/git git init empty export GIT_ALTERNATE_OBJECT_DIRECTORIES=$src/.git/objects strace -fe openat \ git -C empty rev-list --objects $(git -C $src rev-parse HEAD) >/dev/null In v2.50, we see almost no loose object open calls, because we check the pack first. But in v2.54, we see tons of them. > 2.50 does not do this. In most customer deployments of Bitbucket, > the Git data lives on an NFS share. The extra latency on NFS makes > this process of checking for non-existent loose objects take too > long, the push essentially hangs at the "Checking connectivity" step. Yeah, I can imagine. But even on a fast filesystem, we definitely want to avoid all of those syscalls. Replacing "strace" above with a timing harness, even on a system with fast syscalls and a warm cache, the v2.54 version is ~12% slower. > I believe this new behavior was introduced in the recent object > database rework. After using bisect, I belive the problem can be > traced back to commit 8384cbcb4c. Hmm, my bisect ended up at a593373b09 (packfile: refactor `find_pack_entry()` to work on the packfile store, 2026-01-09), which is nearby. I'm not sure if it might depend on other factors (e.g., presence of commit graphs, midx, etc) or my reproduction is not exactly like yours, or if one of us messed up bisection. +cc Patrick as the author of both commits. > I don't know the codebase well, but from what I can see is that > the order in which objects are looked up in object databases > changed. > > Assuming there are two object databases configured (Main repo, > and the quarantine directory, for example), the lookup order used > to be: > > 1. _quarantine dir_ packs > 2. _main dir_ packs > 3. _quarantine dir_ loose objects > 4. _main dir_ loose objects > > With Git 2.54, the order appears to have changed to: > > 1. _quarantine dir_ packs > 2. _quarantine dir_ loose objects > 3. _main dir_ packs > 4. _main dir_ loose objects > > In my testing, within a well-packed repo, Git 2.50 actually never > performed a loose object lookup. Yeah, and that type of regression makes sense for what a593373b09 was trying to do. But I think the v2.54 behavior is wrong. We should check all packs before any loose objects. I'm not sure of the correct fix. This is working against the whole "odb sources are independent and abstract" refactoring that a593373b09 was going for. But I think it's an important optimization. I guess the abstract version would be that each source has "fast" and "slow" lookups or something like that, and we check all fast ones before slow ones. But that is pretty gross. I'll leave it to Patrick to ponder further. I haven't really been paying a lot of attention to the odb refactoring. -Peff ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Performance regression in connectivity check during receive-pack (git 2.54) 2026-07-21 3:57 ` Jeff King @ 2026-07-21 5:05 ` Taylor Blau 2026-07-21 14:40 ` Junio C Hamano 1 sibling, 0 replies; 8+ messages in thread From: Taylor Blau @ 2026-07-21 5:05 UTC (permalink / raw) To: Jeff King; +Cc: Wolfgang Kritzinger, Patrick Steinhardt, git On Mon, Jul 20, 2026 at 11:57:33PM -0400, Jeff King wrote: > On Tue, Jul 21, 2026 at 03:17:23PM +1200, Wolfgang Kritzinger wrote: > > > `strace` shows that after a push, 2.54 does a failing open() of > > of numerous loose objects -- once in the quarantine (incoming) > > directory and once in the main object store -- before finding it > > in a pack: > > > > openat(".../objects/tmp_objdir-incoming-XXXX/ed/58..", O_RDONLY) = ENOENT > > openat(".../objects/ed/58..", O_RDONLY) = ENOENT > > Interesting. Here's a smaller reproduction recipe that shows the issue: > > # clone of git.git, or any other non-trivial repo; it should be mostly > # packed > src=/path/to/git > > git init empty > export GIT_ALTERNATE_OBJECT_DIRECTORIES=$src/.git/objects > strace -fe openat \ > git -C empty rev-list --objects $(git -C $src rev-parse HEAD) >/dev/null > > In v2.50, we see almost no loose object open calls, because we check the > pack first. But in v2.54, we see tons of them. > > > 2.50 does not do this. In most customer deployments of Bitbucket, > > the Git data lives on an NFS share. The extra latency on NFS makes > > this process of checking for non-existent loose objects take too > > long, the push essentially hangs at the "Checking connectivity" step. > > Yeah, I can imagine. But even on a fast filesystem, we definitely want > to avoid all of those syscalls. Replacing "strace" above with a timing > harness, even on a system with fast syscalls and a warm cache, the v2.54 > version is ~12% slower. > > > I believe this new behavior was introduced in the recent object > > database rework. After using bisect, I belive the problem can be > > traced back to commit 8384cbcb4c. > Hmm, my bisect ended up at a593373b09 (packfile: refactor > `find_pack_entry()` to work on the packfile store, 2026-01-09), which is > nearby. I'm not sure if it might depend on other factors (e.g., presence > of commit graphs, midx, etc) or my reproduction is not exactly like > yours, or if one of us messed up bisection. > > +cc Patrick as the author of both commits. I think that both bisection results are equally valid for different reasons. Before 8384cbcb4c, 'find_pack_entry()' did packfile_store_prepare(r->objects->sources->packfiles); , then tried each of the stores in order to first see if (1) a MIDX was available to locate the object in some pack, or (2) failing that, if there exists some non-MIDX'd pack which could do the same. Worth noting is that 'packfile_store_prepare()' effectively did: for (s = store->source->odb->sources; s; s = s->next) { prepare_multi_pack_index_one(s); prepare_packed_git_one(s); } Thus preparing the first store also prepared every alternate store, enabling 'find_pack_entry()' to search through all store's MIDX and pack lists/sources. 8384cbcb4c changes this such that 'packfile_store_prepare()' now only prepares its owning source: prepare_multi_pack_index_one(store->source); prepare_packed_git_one(store->source); , which is reasonable, but 'find_pack_entry()' still loops over all sources starting from 'r->objects->sources' and calls the function 'packfile_store_prepare()'. But! It calls that function over the same argument each time, like so: for (source = r->objects->sources; source; source = source->next) { packfile_store_prepare(r->objects->sources->packfiles); if (source->midx && fill_midx_entry(source->midx, oid, e)) return 1; } So we never prepare the packfile store from other sources! In Wolfgang's case, if we have an quarantine store followed by the main object store, our lookup order will be: 1. prepare the quarantine object store 2. search packs in the quarantine object store 3. search packs in the main object store (which will fail, since this list is guaranteed to be empty since we never called 'packfile_store_prepare()') 4. search loose objects in the quarantine object store 5. search loose objects in the main object store 6. haven't found anything, so we must reprepare 7. search packs in the main object store, which will now succeed, as the previous reprepare called 'packfile_store_prepare()' on the main object store's packfile source. Commit a593373b09 changes things, since it makes 'find_pack_entry()' no longer operate over the entire repository, but over a single store. Before searching that store, it prepares it, like so: static int find_pack_entry(struct packfile_store *store, const struct object_id *oid, sturct pack_entry *e) { struct packfile_list_entry *l; packfile_store_prepare(store); if (store->source->midx && fill_midx_entry(...)) return 1; for (l = store->packs.head; l; l = l->next) { struct packed_git *p = l->pack; if (!p->multi_pack_index && fill_pack_entry(oid, e, p)) { /* ... */ return 1; } } return 0; } So commit a593373b09 indeed squashes the bug introduced by 8384cbcb4c, and when lookup reaches the main store, it prepares the main store correctly. But a593373b09 also changes the lookup order, because the caller in 'do_oid_object_info_extended()` already loops over sources! static int do_oid_object_info_extended(struct object_database *odb, const struct object_id *oid, struct object_info *oi, unsigned flags) { /* replace objects, cached lookups, etc., ... */ odb_prepare_alterantes(odb); while (1) { struct odb_source *source; for (source = odb->sources; source; source = source->next) { if (!packfile_store_read_object_info(source->packfiles, real, oi, flags) || !odb_source_loose_read_object_info(source, real, oi, flags)) return 0; } } } Before a593373b09, that call to 'packfile_store_read_object_info()' looped over all sources, since it still called 'find_pack_entry()'. In other words, prior to a593373b09, the lookup proceeded like so: 1. search packfiles in quarantine 2. search packfiles in the main object store 3. search loose objects in quarantine 4. search loose objects in the main object store But a593373b09 changes that to instead proceed store-by-store, as follows: 1. search packfiles in quarantine 2. search loose objects in quarantine 3. search packfiles in the main object store 4. search loose objects in the main object store So even with all object sources prepared, every object found in a later source pays a failed loose object lookup in an earlier one, which I believe matches what Peff strace'd above. So both bisections make sense. If the later store has not been prepared yet, commit 8384cbcb4c is where Git first fails to see its packs and falls through to loose object checks. If the stores are already prepared, that problem does not show up, and a593373b09 is where Git first starts checking loose objects in an earlier source before looking in a later source's packs. I think that something like the following (untested) would fix the immediate issue: --- 8< --- diff --git a/odb.c b/odb.c index cf6e7938c0..aeb2915f0f 100644 --- a/odb.c +++ b/odb.c @@ -568,9 +568,28 @@ static int do_oid_object_info_extended(struct object_database *odb, while (1) { struct odb_source *source; - for (source = odb->sources; source; source = source->next) - if (!odb_source_read_object_info(source, real, oi, flags)) + /* + * Check all packed sources before trying loose ones. A loose + * miss requires a filesystem lookup, and receive-pack's + * quarantine source makes the main object directory an + * alternate. + */ + for (source = odb->sources; source; source = source->next) { + struct odb_source_files *files = + odb_source_files_downcast(source); + + if (!odb_source_read_object_info(&files->packed->base, + real, oi, flags)) return 0; + } + for (source = odb->sources; source; source = source->next) { + struct odb_source_files *files = + odb_source_files_downcast(source); + + if (!odb_source_read_object_info(&files->loose->base, + real, oi, flags)) + return 0; + } /* * When the object hasn't been found we try a second read and --- >8 --- But... > I'm not sure of the correct fix. This is working against the whole "odb > sources are independent and abstract" refactoring that a593373b09 was > going for. But I think it's an important optimization. I guess the > abstract version would be that each source has "fast" and "slow" lookups > or something like that, and we check all fast ones before slow ones. But > that is pretty gross. ...that fix is breaking the very abstraction that the pluggable-ODB effort is trying to create in the first place, at least in my understanding of the project's goals. > I'll leave it to Patrick to ponder further. I haven't really been paying > a lot of attention to the odb refactoring. I am genuinely not sure what the right path forward here is, given that I do not have a super firm understanding of all of the refactoring that has taken place here. I would be likewise eager to hear from Patrick or others with thoughts on how to resolve this. Thanks, Taylor ^ permalink raw reply related [flat|nested] 8+ messages in thread
* Re: Performance regression in connectivity check during receive-pack (git 2.54) 2026-07-21 3:57 ` Jeff King 2026-07-21 5:05 ` Taylor Blau @ 2026-07-21 14:40 ` Junio C Hamano 2026-07-22 11:49 ` Patrick Steinhardt 1 sibling, 1 reply; 8+ messages in thread From: Junio C Hamano @ 2026-07-21 14:40 UTC (permalink / raw) To: Jeff King; +Cc: Wolfgang Kritzinger, Patrick Steinhardt, git Jeff King <peff@peff.net> writes: > Yeah, and that type of regression makes sense for what a593373b09 was > trying to do. But I think the v2.54 behavior is wrong. We should check > all packs before any loose objects. > > I'm not sure of the correct fix. This is working against the whole "odb > sources are independent and abstract" refactoring that a593373b09 was > going for. But I think it's an important optimization. I guess the > abstract version would be that each source has "fast" and "slow" lookups > or something like that, and we check all fast ones before slow ones. But > that is pretty gross. > > I'll leave it to Patrick to ponder further. I haven't really been paying > a lot of attention to the odb refactoring. I think checking the fast sources before the slow ones is probably the best we can do if we want to retain the 'each odb source is an opaque object' abstraction. Stepping back a bit, the 'rev-list' command used for the connectivity check is curious in multiple aspects. * On the surface, it looks as if the caller wants an enumeration of all objects that appear in the range. However, the caller is not interested in the actual list of objects. Instead, they are interested only in a single bit: whether the traversal succeeds or dies due to a missing object. This is because the traversal determines whether we need to fetch, or whether we are already up to date, to decide whether the proposed 'fetch' is a no-op. The positive ends of the traversal represent what we are about to fetch; if we already have all the objects needed to reach those tips in our repository, we can do without actually downloading anything [*]. * A false positive answer to the question "does the traversal die due to a missing object?" does not affect correctness, as this is merely an optimization to save downloads (though a false negative is unacceptable). Given this non-standard use of the command, we can pass application-specific cues (such as "we are doing this traversal for a connectivity check") down to the machinery as a hint to help it optimize its operation, and I suspect that such a hint might have value. For example, we could enumerate all loose objects in the loose object store using 256 opendir() and readdir() calls for about 10,000 files (since once you have more than 6,700 loose objects, auto-gc would pack them) and store them in an in-core table [**]. This would enable us to say "the object with that name does not exist here" without running lstat() at all. I wonder how many lstat() calls we would need to save for such a scheme to pay off. There may be other highly application-specific optimization opportunities, as utilizing revision traversal for connectivity checking has peculiar correctness requirements that differ from the normal use of the API. [Footnote] * It follows that in a lazily cloned repository with promisor remotes, the traversal could download everything needed as it goes, only to conclude: "No need for the main fetch; we have everything we need." I would expect this to be a fairly slow process that defeats the entire reason we have this connectivity check up front as an optimization. While I have not checked, I believe the actual code prevents this either by skipping the connectivity check altogether, or by instructing the connectivity checker to treat promised (but not immediately available) objects as missing and abort. But my point is that theoretically one does not even need 'git fetch' in a lazily cloned repository. It is sufficient to use 'git ls-remote' to determine the tips of remote refs, and run 'rev-list' to fill the range. ** If in-core memory pressure is a concern, we could use a Bloom filter, as we only need to know "the object is definitely not here" and can tolerate "that object might be here, but we are not certain." ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Performance regression in connectivity check during receive-pack (git 2.54) 2026-07-21 14:40 ` Junio C Hamano @ 2026-07-22 11:49 ` Patrick Steinhardt 2026-07-22 15:49 ` Junio C Hamano 0 siblings, 1 reply; 8+ messages in thread From: Patrick Steinhardt @ 2026-07-22 11:49 UTC (permalink / raw) To: Junio C Hamano; +Cc: Jeff King, Wolfgang Kritzinger, git, jltobler On Tue, Jul 21, 2026 at 07:40:02AM -0700, Junio C Hamano wrote: > Jeff King <peff@peff.net> writes: > > > Yeah, and that type of regression makes sense for what a593373b09 was > > trying to do. But I think the v2.54 behavior is wrong. We should check > > all packs before any loose objects. > > > > I'm not sure of the correct fix. This is working against the whole "odb > > sources are independent and abstract" refactoring that a593373b09 was > > going for. But I think it's an important optimization. I guess the > > abstract version would be that each source has "fast" and "slow" lookups > > or something like that, and we check all fast ones before slow ones. But > > that is pretty gross. > > > > I'll leave it to Patrick to ponder further. I haven't really been paying > > a lot of attention to the odb refactoring. > > I think checking the fast sources before the slow ones is probably > the best we can do if we want to retain the 'each odb source is an > opaque object' abstraction. Seeing that this is about the `tmp_objdir` case: one of the things that Justin and I wanted to work on anyway is that we want to stop modifying the list of sources during transactions in the first place. It always felt kind of gross that we're modifying the sources when creating a transaction, as the only reason that we do this for is so that the writes actually go to the temporary object directory instead of to the primary object source. And that doesn't make a lot of sense to begin with. The alternative to this would be to instead have logic in functions like `odb_write()` that checks whether we have an active transaction or not. If so, the write would go into the transaction directly instead of going into the primary source, and consequently we wouldn't even have to modify the list of sources at all. This shouldn't create too much of a problem, as we typically don't intend to even read objects that we've written into the transaction immediately. It would avoid that we try to read objects from the temporary object directory. And it would also allow us to eventually move all the logic to write objects into the transactions exclusively. I'm currently out of office though, and will be on vacation next week. I'll explore this area a bit more though once I'm back in office in two weeks. Patrick ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Performance regression in connectivity check during receive-pack (git 2.54) 2026-07-22 11:49 ` Patrick Steinhardt @ 2026-07-22 15:49 ` Junio C Hamano [not found] ` <20260723104943.GC604358@coredump.intra.peff.net> 0 siblings, 1 reply; 8+ messages in thread From: Junio C Hamano @ 2026-07-22 15:49 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: Jeff King, Wolfgang Kritzinger, git, jltobler Patrick Steinhardt <ps@pks.im> writes: > The alternative to this would be to instead have logic in functions like > `odb_write()` that checks whether we have an active transaction or not. > If so, the write would go into the transaction directly instead of going > into the primary source, and consequently we wouldn't even have to > modify the list of sources at all. > > This shouldn't create too much of a problem, as we typically don't > intend to even read objects that we've written into the transaction > immediately. It would avoid that we try to read objects from the > temporary object directory. And it would also allow us to eventually > move all the logic to write objects into the transactions exclusively. I suspect several of those 'transactions' are actually misspelt 'temporary directories', but I catch your drift. That said, a redesign like that feels more or less independent of the fix for our immediate performance regression. After all, didn't Peff show us a case where no odb sources were being flipped in the middle? Simply setting up one object store to borrow from another via the alternates mechanism demonstrated that checking packs across all object stores before hunting for loose objects in any of them makes a world of difference. > I'm currently out of office though, and will be on vacation next week. > I'll explore this area a bit more though once I'm back in office in two > weeks. Understood. Bon voyage and have fun! ^ permalink raw reply [flat|nested] 8+ messages in thread
[parent not found: <20260723104943.GC604358@coredump.intra.peff.net>]
* Re: Performance regression in connectivity check during receive-pack (git 2.54) [not found] ` <20260723104943.GC604358@coredump.intra.peff.net> @ 2026-07-24 3:46 ` Patrick Steinhardt 2026-07-26 8:51 ` Jeff King 0 siblings, 1 reply; 8+ messages in thread From: Patrick Steinhardt @ 2026-07-24 3:46 UTC (permalink / raw) To: Jeff King; +Cc: Junio C Hamano, Wolfgang Kritzinger, git, jltobler On Thu, Jul 23, 2026 at 06:49:43AM -0400, Jeff King wrote: > On Wed, Jul 22, 2026 at 08:49:50AM -0700, Junio C Hamano wrote: > > > I suspect several of those 'transactions' are actually misspelt > > 'temporary directories', but I catch your drift. That said, a > > redesign like that feels more or less independent of the fix for our > > immediate performance regression. > > > > After all, didn't Peff show us a case where no odb sources were > > being flipped in the middle? Simply setting up one object store to > > borrow from another via the alternates mechanism demonstrated that > > checking packs across all object stores before hunting for loose > > objects in any of them makes a world of difference. > > Yeah, exactly. This is really a regression in alternates performance, > but it just so happens that the quarantine system is built on top of > alternates so we noticed it there. > > I'd expect "clone -s / --reference" to have similar problems, and also > for sites like GitHub and GitLab that make heavy use of alternates for > object sharing between forks. And those would pay the penalty on just > about every operation (because we'd expect the alternate to be holding > most of the objects in those cases). You're right, I also realized that after sending my mail. One other angle that Justin and I have been discussing (we were at an offsite together over the last couple days) was that we can do a small course correction: instead of handling alternates on the ODB level, we may be able to start treating alternates as an implementation detail of it. So both the handling of alternates, but also the handling of the GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES environment variables would be moved into the "files" backend itself. This would solve a bunch of smaller issues that we're currently grappling with where some of the concepts in Git really want to operate across all of the alternates: - The OBJECT_INFO_SECOND_READ flag can be dropped as it becomes an implementation detail. - We can fix the performance regression because we can now easily reorder access to read via packfiles first across all sub-sources. - Commit graphs and bitmap really are a singleton, so loading them via multiple sources is awkward. - The object storage extension that I've written got quite a bit ugly as it wasn't quite clear where exactly to draw the line. Especially hadnling the environment variables mentioned above into the "files" backend removes one point of friction I encountered. - Object database maintenance needs to be aware of the other non-local sources. Also, doing that change isn't as bad as it may sound at first. We'd still retain the whole `struct odb_source` list because we want to have them for submodule sources. Furthermore, alternates aren't required for isolation either as we currently use them via the temporary object directory. An alternative implementation may use a completely separate mechanism to achieve write isolation, which is also why we have made the environment variables pluggable that the `struct odb_transaction` ends up passing to the child process. I think overall this could simplify some of the design, and it makes a bunch of issues that I have been struggling with go away. The devil may be in the details of course, but I think transitioning towards this should be doable. So I'll work towards that goal. I've got a patch series already that removes all of our calls to `odb_prepare_alternates()` as a first step, but I'll only send that in two weeks once I'm back in office. I'll then have a look at how bad the subsequent steps would be. Thanks! Patrick ^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: Performance regression in connectivity check during receive-pack (git 2.54) 2026-07-24 3:46 ` Patrick Steinhardt @ 2026-07-26 8:51 ` Jeff King 0 siblings, 0 replies; 8+ messages in thread From: Jeff King @ 2026-07-26 8:51 UTC (permalink / raw) To: Patrick Steinhardt; +Cc: Junio C Hamano, Wolfgang Kritzinger, git, jltobler On Fri, Jul 24, 2026 at 05:46:58AM +0200, Patrick Steinhardt wrote: > One other angle that Justin and I have been discussing (we were at an > offsite together over the last couple days) was that we can do a small > course correction: instead of handling alternates on the ODB level, we > may be able to start treating alternates as an implementation detail of > it. So both the handling of alternates, but also the handling of the > GIT_OBJECT_DIRECTORY and GIT_ALTERNATE_OBJECT_DIRECTORIES environment > variables would be moved into the "files" backend itself. That seems reasonable to me. In theory it could lose some flexibility if some code really wanted to represent alternates as abstract sources, but I can't think of why you'd want to do so. Traditionally we did not even really have separate sources at all, and the point of adding them was not so much to have arbitrary combinations of sources as to abstract the details. I guess somebody could want to use a local alternates object-dir along with their sql database of objects or whatever. But even then, it seems like the alternate could be added as its own files-backend odb source. > This would solve a bunch of smaller issues that we're currently > grappling with where some of the concepts in Git really want to operate > across all of the alternates: > [...] Yeah, that all sounds like a positive direction. Thanks! -Peff ^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2026-07-26 8:51 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-21 3:17 Performance regression in connectivity check during receive-pack (git 2.54) Wolfgang Kritzinger
2026-07-21 3:57 ` Jeff King
2026-07-21 5:05 ` Taylor Blau
2026-07-21 14:40 ` Junio C Hamano
2026-07-22 11:49 ` Patrick Steinhardt
2026-07-22 15:49 ` Junio C Hamano
[not found] ` <20260723104943.GC604358@coredump.intra.peff.net>
2026-07-24 3:46 ` Patrick Steinhardt
2026-07-26 8:51 ` Jeff King
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox