Skip to content

Same repository requested with and without a trailing .git gets two mirrors, two fetches and two cache entries #57

Description

@matt-edmondson

What's wrong

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

  1. The service runs with --allow github=studio/*.
  2. Client A posts to /v1/github/studio/game.git/state and client B posts to /v1/github/studio/game/state.
  3. 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.
  4. The result for a single repository is double the disk use, double the upstream fetches, and double the admission probes. That is the duplication Same repository gets mirrored, fetched and diffed twice when callers vary path casing #24 and Upstream key casing isn't canonicalized, duplicating mirrors like the already-fixed repository-path case bug #37 removed for casing.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions