What's wrong
SyncGitHubRepoInfoForOwner (ProjectDirector/ProjectDirector.cs, ~lines 1015–1030) overwrites Options.Repos[repoName] unconditionally with a new repo whose LocalPath is DevDirectory/<owner>/<repo>. It does this even when the repo is already known and cloned somewhere else.
UpdateClonedStatus() (~lines 1041–1053) walks only Options.Repos, so it never removes the old ClonedRepos entry, which is still keyed by the real clone path.
Failure scenario (the documented flow)
- Scan Dev Dir finds
<dev>/ProjectDirector, whose origin is https://github.com/ktsu-dev/ProjectDirector.git. It sets Repos["ktsu-dev.ProjectDirector"].LocalPath = <dev>/ProjectDirector, records ClonedRepos[<dev>/ProjectDirector] = ktsu-dev.ProjectDirector, and adds ktsu-dev to the owners.
- Scan GitHub Owners replaces that entry.
LocalPath becomes <dev>/ktsu-dev/ProjectDirector, which doesn't exist.
- The stale entry
ClonedRepos[<dev>/ProjectDirector] survives. The result:
FetchAllReposIfStale runs git -C <dev>/ktsu-dev/ProjectDirector fetch every 60 seconds and logs a failure each time.
- The Git Actions panel decides "cloned" from
ClonedRepos.ContainsValue(...), so it shows Pull, Commit and Push, and all three fail. The Clone button is hidden.
- The repo drops out of sibling comparisons.
This hits every repo that isn't laid out as <dev>/<owner>/<repo>. That is the normal case for anyone whose clones sit directly under their dev directory, and it follows from Scan Dev Dir adding the owners itself.
(Traced from the code; not run end-to-end, because it needs GitHub API access.)
Suggested fix
- In
SyncGitHubRepoInfoForOwner, if Options.Repos already holds the repo and its LocalPath is a cloned repository, keep that LocalPath and just update the metadata.
- In
UpdateClonedStatus(), also prune ClonedRepos entries whose key no longer equals their repo's LocalPath.
Acceptance criteria
Running Scan Dev Dir and then Scan GitHub Owners keeps each already-cloned repo pointing at its actual clone, and it leaves no stale ClonedRepos entries behind.
What's wrong
SyncGitHubRepoInfoForOwner(ProjectDirector/ProjectDirector.cs, ~lines 1015–1030) overwritesOptions.Repos[repoName]unconditionally with a new repo whoseLocalPathisDevDirectory/<owner>/<repo>. It does this even when the repo is already known and cloned somewhere else.UpdateClonedStatus()(~lines 1041–1053) walks onlyOptions.Repos, so it never removes the oldClonedReposentry, which is still keyed by the real clone path.Failure scenario (the documented flow)
<dev>/ProjectDirector, whose origin ishttps://github.com/ktsu-dev/ProjectDirector.git. It setsRepos["ktsu-dev.ProjectDirector"].LocalPath = <dev>/ProjectDirector, recordsClonedRepos[<dev>/ProjectDirector] = ktsu-dev.ProjectDirector, and addsktsu-devto the owners.LocalPathbecomes<dev>/ktsu-dev/ProjectDirector, which doesn't exist.ClonedRepos[<dev>/ProjectDirector]survives. The result:FetchAllReposIfStalerunsgit -C <dev>/ktsu-dev/ProjectDirector fetchevery 60 seconds and logs a failure each time.ClonedRepos.ContainsValue(...), so it shows Pull, Commit and Push, and all three fail. The Clone button is hidden.This hits every repo that isn't laid out as
<dev>/<owner>/<repo>. That is the normal case for anyone whose clones sit directly under their dev directory, and it follows from Scan Dev Dir adding the owners itself.(Traced from the code; not run end-to-end, because it needs GitHub API access.)
Suggested fix
SyncGitHubRepoInfoForOwner, ifOptions.Reposalready holds the repo and itsLocalPathis a cloned repository, keep thatLocalPathand just update the metadata.UpdateClonedStatus(), also pruneClonedReposentries whose key no longer equals their repo'sLocalPath.Acceptance criteria
Running Scan Dev Dir and then Scan GitHub Owners keeps each already-cloned repo pointing at its actual clone, and it leaves no stale
ClonedReposentries behind.