From: Patrick Steinhardt <ps@pks.im>
To: Jeff King <peff@peff.net>
Cc: git@vger.kernel.org, Justin Tobler <jltobler@gmail.com>
Subject: Re: [PATCH v2 1/4] odb: decouple source path comparisons from `the_repository`
Date: Mon, 17 Aug 2026 09:16:53 +0200 [thread overview]
Message-ID: <aoK1ZYfqh5PnNin6@pks.im> (raw)
In-Reply-To: <aoKeeQMps50rjhWi@pks.im>
On Mon, Aug 17, 2026 at 07:39:05AM +0200, Patrick Steinhardt wrote:
> On Fri, Aug 14, 2026 at 01:17:24PM -0400, Jeff King wrote:
> > On Wed, Aug 12, 2026 at 11:13:57AM +0200, Patrick Steinhardt wrote:
> >
> > > When registering alternates we deduplicate object database sources by
> > > their path so that the same source won't be added twice. Ever since
> > > cf2dc1c238 (speed up alt_odb_usable() with many alternates, 2021-07-07)
> > > this duplicate check is backed by a map keyed by the source's path,
> > > using `fspathhash()` and `fspatheq()` as hash and equality functions,
> > > respectively.
> > >
> > > These functions are problematic in this context for two reasons:
> > >
> > > - They implicitly depend on `the_repository` instead of the
> > > repository that owns the object database.
> >
> > I'm not even sure that using core.ignorecase here is strictly correct.
> > It is a property of the containing repository, and the filesystem in
> > which it's stored. But there is no guarantee that the alternate
> > directories are in the same repository, or even the same filesystem!
> >
> > So it is really just a best guess proxy for "this system tends to use or
> > not use case insensitive filesystems[1]". It can be wrong in both
> > directions (failing to suppress duplicates, and suppressing them when
> > they are not actually duplicates).
> >
> > I wonder how bad it would be if we just always did case-sensitive
> > comparisons and made it the caller's responsibility to spell things
> > consistently. I guess some names ultimately come from things like
> > "--reference" command-line arguments, so that would depend on user
> > spelling. But having duplicates at all is kind of unlikely (you can't
> > get it from one --reference clone, but rather a complex tree of
> > interwoven repos with shared roots).
> >
> > How bad is a duplicate alternate? It's a minor performance issue, I'd
> > think. We would add its packs to the list (though hardly ever look
> > through them, as the "first" copy would satisfy most requests, and the
> > unused second copies end up at the back of the MRU list). You'd only pay
> > the extra lookup cost for an object which we fail to find entirely,
> > which is rare-ish (mostly speculative lookups for fetches).
>
> A performance regression is definitely the most likely change in
> behaviour we might see because of this. One other part I am a bit
> worried about is housekeeping, but I think we should be fine there as we
> only consider the primary source as special.
>
> I also had the feeling that case insensitivity is quite a bit lacking,
> too. What we're really after is whether two directories are actually the
> exact same path. And whether the path is case-insensitive is only one
> part of that equation, so it's an imperfect metric by itself already.
>
> Ideally, we should probably use realpath(3p) to at least also resolve
> symlinks. Unfortunately, it's not guaranteed that this function also
> knows to canonicalize casing.
>
> > And it would fix the unlikely-but-possible opposite case of suppressing
> > a non-duplicate. If you have a repo on a case-insensitive filesystem
> > with two alternates on a case-sensitive system that differ only in case,
> > we erroneously suppress one of them, and commands may fail to find
> > objects we should have. Of course that's super unlikely, which is why
> > nobody has run into it before.
> >
> > So I kind of wonder if we could just do away with considering case
> > insensitivity here at all. We'd err on the side of correctness in the
> > ambiguous cases, and this code complexity can just go away.
>
> You will of course be able to craft edge cases where that would be a
> significant regression. But if your alternates file looks like this you
> may be holding it wrong:
>
> /path/to/alternate
> /PATH/TO/ALTERNATE
> /pAtH/tO/aLtErNaTe
> /PaTh/To/AlTeRnAtE
>
> > Alternatively, I think we could probably make the check more thorough in
> > a similar way. Always consider a pair of case-insensitive matches as
> > possible duplicates, and then for each possible duplicate use stat() to
> > check their st_dev and st_ino values. That keeps things cheap for normal
> > cases, and we pay only the stat() before de-duping. It's correct and
> > doesn't rely on the repo, though it is a bit more somewhat complicated
> > code.
>
> Hm. Weren't there filesystems where `st_ino` and `st_dev` aren't set at
> all? I think that's the case on Windows, which is unfortunately also the
> one where we see case insensitive filesystems by default. So that makes
> it way less effective, as it only works on systems where we typically
> aren't case-insensitive in the first place (except macOS maybe).
>
> So if we want to go down this path I'm inclined to just unconditionally
> use case sensitive matching and not introduce any secondary machinery.
Thinking about this a bit more: I'd suggest that we leave this out of
this patch and instead document this as a NEEDSWORK area for now. I
_think_ that this proposed refactoring should be generally fine, and I
quite like the simplification that results from it. But the risk for
regression is quite a bit higher compared to the origanal patch that
I've proposed.
Patrick
next prev parent reply other threads:[~2026-08-17 7:17 UTC|newest]
Thread overview: 41+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-10 13:33 [PATCH 0/4] odb: eagerly load alternates Patrick Steinhardt
2026-08-10 13:33 ` [PATCH 1/4] odb: decouple source path comparisons from `the_repository` Patrick Steinhardt
2026-08-11 22:04 ` Justin Tobler
2026-08-12 5:39 ` Patrick Steinhardt
2026-08-10 13:33 ` [PATCH 2/4] odb: eagerly initialize alternates Patrick Steinhardt
2026-08-11 22:15 ` Justin Tobler
2026-08-12 5:39 ` Patrick Steinhardt
2026-08-10 13:33 ` [PATCH 3/4] odb: drop `loaded_alternates` field Patrick Steinhardt
2026-08-11 22:22 ` Justin Tobler
2026-08-10 13:33 ` [PATCH 4/4] odb: drop `alternates_db` field Patrick Steinhardt
2026-08-11 22:31 ` Justin Tobler
2026-08-12 5:39 ` Patrick Steinhardt
2026-08-12 9:13 ` [PATCH v2 0/4] odb: eagerly load alternates Patrick Steinhardt
2026-08-12 9:13 ` [PATCH v2 1/4] odb: decouple source path comparisons from `the_repository` Patrick Steinhardt
2026-08-13 12:23 ` Karthik Nayak
2026-08-13 13:17 ` Patrick Steinhardt
2026-08-14 10:21 ` Karthik Nayak
2026-08-14 17:17 ` Jeff King
2026-08-14 19:03 ` Junio C Hamano
2026-08-14 20:36 ` Jeff King
2026-08-17 5:39 ` Patrick Steinhardt
2026-08-17 7:16 ` Patrick Steinhardt [this message]
2026-08-17 7:36 ` Jeff King
2026-08-17 9:42 ` Patrick Steinhardt
2026-08-17 7:28 ` Jeff King
2026-08-14 17:21 ` Jeff King
2026-08-17 5:36 ` Patrick Steinhardt
2026-08-12 9:13 ` [PATCH v2 2/4] odb: eagerly initialize alternates Patrick Steinhardt
2026-08-12 9:13 ` [PATCH v2 3/4] odb: drop `loaded_alternates` field Patrick Steinhardt
2026-08-13 12:25 ` Karthik Nayak
2026-08-12 9:14 ` [PATCH v2 4/4] odb: drop `alternates_db` field Patrick Steinhardt
2026-08-12 15:38 ` [PATCH v2 0/4] odb: eagerly load alternates Junio C Hamano
2026-08-13 8:56 ` Patrick Steinhardt
2026-08-13 12:28 ` Karthik Nayak
2026-08-13 17:09 ` Justin Tobler
2026-08-17 11:09 ` [PATCH v3 0/5] " Patrick Steinhardt
2026-08-17 11:09 ` [PATCH v3 1/5] setup: create ref and object databases after config is written Patrick Steinhardt
2026-08-17 11:09 ` [PATCH v3 2/5] odb: decouple source path comparisons from `the_repository` Patrick Steinhardt
2026-08-17 11:09 ` [PATCH v3 3/5] odb: eagerly initialize alternates Patrick Steinhardt
2026-08-17 11:09 ` [PATCH v3 4/5] odb: drop `loaded_alternates` field Patrick Steinhardt
2026-08-17 11:09 ` [PATCH v3 5/5] odb: drop `alternates_db` field Patrick Steinhardt
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=aoK1ZYfqh5PnNin6@pks.im \
--to=ps@pks.im \
--cc=git@vger.kernel.org \
--cc=jltobler@gmail.com \
--cc=peff@peff.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox