fix: stop the idle-mirror sweep reaping a live mirror under a mirror.git path segment [patch] - #49
Merged
Merged
Conversation
…git path segment [patch] The repository studio/mirror is stored at studio/mirror.git/mirror.git, so Enumerate() also returned the parent path segment as a mirror. The parent never carries a marker, looked idle from the day it was created, and was reaped along with the live mirror inside it. It was also measured, which double-counted the mirror's bytes. Enumerate() now drops a mirror.git directory that holds another candidate and has no files of its own, which a bare repository always has. The sweep also refuses to reap a mirror that holds another enumerated mirror, and measures only its own files. Fixes #42 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PtWVWaDh3nqJL1eKD7vFxU
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Fixes #42
What was wrong
Clients send repository paths with a
.gitsuffix, so the repositorystudio/mirroris stored at<root>/github/studio/mirror.git/mirror.git.MirrorStore.Enumerate()returned every directory namedmirror.git, including the parent path segment. That parent never gets a marker, soLastTouchedfell back to its creation time. AfterMirrorIdleMaxAgethe sweep reaped it recursively, and the live mirror inside went with it. Until then, the mirror's bytes were also counted twice.Change
MirrorStore.Enumerate()drops amirror.gitcandidate that contains another candidate and has no files of its own. A real mirror is a bare repository, so it always has at leastHEAD. A path-segment directory has only subdirectories. Leafmirror.gitdirectories are still listed as before, including empty ones and half-written ones.MirrorMaintenanceService.Sweep()covers the remaining case, where a real mirror holds another real mirror (repositorystudioalongsidestudio/mirror.git):MirrorStore.IsInside(path, directory), a strict-descendant check that both classes share.I didn't reject
mirror.gitinIsSafeSegment, which the issue also suggested. That would make a repository literally namedmirrorimpossible to serve.Tests
MirrorStoreTests.Enumerate_ARepositoryNamedMirror_ListsOnlyTheMirrorAndNotItsPathSegmentMirrorStoreTests.Enumerate_AMirrorHoldingAnotherMirror_ListsBothMirrorMaintenanceServiceTests.Sweep_ARepositoryNamedMirrorStillBeingQueried_IsKept: the issue's scenario, 40 days in with fresh markers.MockFileSystemstamps creation times from the real clock, so the test pins the path segment's creation time to the fake clock.MirrorMaintenanceServiceTests.Sweep_AnIdleMirrorHoldingALiveMirror_IsKeptResults:
Mirrors/*.csreverted, 3 of the new tests fail.Enumerate_AMirrorHoldingAnotherMirror_ListsBothis a guard and passes either way.dotnet test --project GitBranchStateCache.Tests).🤖 Generated with Claude Code
https://claude.ai/code/session_01PtWVWaDh3nqJL1eKD7vFxU
Generated by Claude Code