You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
GitBranchStateCache/Endpoints/BranchStateHandler.cs builds the mirror key as new MirrorKey(Canonicalize(route.Upstream), Canonicalize(route.RepositoryPath)) (~L410). Canonicalize (~L452) is only segment.ToLowerInvariant().
#24 and #37 made casing irrelevant, but a trailing .git still produces a different key. Remotes are routinely cloned both ways (https://github.com/studio/game and https://github.com/studio/game.git), and any allow-list entry with a wildcard admits both spellings.
Failure scenario
The service runs with --allow github=studio/*.
Client A posts to /v1/github/studio/game.git/state and client B posts to /v1/github/studio/game/state.
MirrorStore.TryResolve lays these out as two mirrors, studio/game.git/mirror.git and studio/game/mirror.git. Each has its own single-flight key, diff-cache key and admission key.
A side effect is that the studio/game.git/… layout creates the mirror.git path-segment case that #42 had to special-case in the idle sweep.
Suggested fix / acceptance criteria
In Canonicalize, or in the key built from the repository path, strip a single trailing .git (case-insensitively) for bookkeeping only. The URL sent to the forge keeps the caller's spelling.
Test: requests for studio/game and studio/game.git resolve to the same MirrorKey and share a single fetch.
Note in the changelog that existing *.git/ mirrors are re-cloned once under the new key. The idle sweep reaps the old ones.
What's wrong
GitBranchStateCache/Endpoints/BranchStateHandler.csbuilds the mirror key asnew MirrorKey(Canonicalize(route.Upstream), Canonicalize(route.RepositoryPath))(~L410).Canonicalize(~L452) is onlysegment.ToLowerInvariant().#24 and #37 made casing irrelevant, but a trailing
.gitstill produces a different key. Remotes are routinely cloned both ways (https://github.com/studio/gameandhttps://github.com/studio/game.git), and any allow-list entry with a wildcard admits both spellings.Failure scenario
--allow github=studio/*./v1/github/studio/game.git/stateand client B posts to/v1/github/studio/game/state.MirrorStore.TryResolvelays these out as two mirrors,studio/game.git/mirror.gitandstudio/game/mirror.git. Each has its own single-flight key, diff-cache key and admission key.A side effect is that the
studio/game.git/…layout creates themirror.gitpath-segment case that #42 had to special-case in the idle sweep.Suggested fix / acceptance criteria
Canonicalize, or in the key built from the repository path, strip a single trailing.git(case-insensitively) for bookkeeping only. The URL sent to the forge keeps the caller's spelling.studio/gameandstudio/game.gitresolve to the sameMirrorKeyand share a single fetch.*.git/mirrors are re-cloned once under the new key. The idle sweep reaps the old ones.