feat: re-analyse a repository at its latest revision - #452
Merged
Merged
Conversation
There was no way to bring an imported repository up to date. The only route to a second revision was retyping the GitHub URL, and if the branch had not moved the answer was "Repository has already been imported" -- a conflict, which reads as a wall rather than as "you are already current". The capability was already there. Re-importing at a new commit has always allocated a new revision in the same lineage (#298/#299/#400): the duplicate check is per-commit, not per-repository. What was missing was any way to ask for it. This is wiring, not engine work. POST /repositories/{id}/reanalyse resolves the branch head, compares it with the lineage's head and reports one of two outcomes. An unmoved branch is `already-current` with the revision it checked named, at 200 -- a state, not an error. A moved one imports through exactly the same path as the first revision, so the lineage, the duplicate check and the sealed snapshot behave identically whichever entry point asked. The head is resolved with `ls-remote`, not a clone. "Has this moved?" is usually answered "no", and answering it by downloading and parsing the whole repository to learn one SHA is a poor trade. A remote answer this client cannot read is reported as a failure rather than being treated as unchanged; reporting a repository current on the strength of a failed lookup is worse than saying the lookup failed. Comparison is against the lineage head, not the revision being viewed: opening revision 1 of a three-revision lineage and asking to re-analyse must not import a fourth copy of something already sealed. An upload has no upstream, so it gets neither the action nor a route that would refuse it: the history panel shows the button only for a lineage. A new revision re-reads the history in place. Closes #448
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
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.
Closes #448. Independent of #450/#451 — branches off
dev.The gap
There was no way to bring an imported repository up to date. The only route to a second revision was retyping the GitHub URL, and if the branch had not moved:
A 409. A wall, where the truthful answer was "you are already current".
The capability already existed
Re-importing at a new commit has always allocated a new revision in the same lineage (#298/#299/#400) — the duplicate check is per-commit, not per-repository.
GET /repositories/{id}/lineagealready serves the history andRepositoryLineageHistoryalready renders it. What was missing was any way to ask. This is wiring, not engine work.POST /repositories/{id}/reanalysealready-currentrevision-importedremoteHeadcomes back either way, so the UI can say which commit it checked rather than asking the reader to trust that it checked.previousRepositoryIdis returned on import — that's the "from" side of a two-revision diff (#219).Three decisions worth naming
The head is resolved with
ls-remote, not a clone. "Has this moved?" is usually answered "no", and answering it by downloading and parsing the whole repository to learn one SHA is a poor trade. NewGitHubClient.read_remote_head_commit, one round trip, no disk.A head this client cannot read is a failure, not "unchanged." Reporting a repository as current on the strength of a failed lookup is worse than saying the lookup failed — 502, with a test pinning it.
Comparison is against the lineage head, not the revision being viewed. Opening revision 1 of a three-revision lineage and asking to re-analyse must not report the branch as moved and import a fourth copy of something already sealed.
Frontend
The action lives in the History panel and appears only for a lineage — an upload has no upstream, so it gets no affordance rather than one that refuses.
already-currentrenders as a neutralrole="status"line naming the commit; a new revision re-reads the history in place and navigates to what it found.Verification
Live, against
pallets/click(real network, dev database):The moved path is covered by tests, not by a live run — no repository in the dev database had moved since import, and I could not fake one:
RepositoryRecordenforces revision immutability (Repository revision identity is immutable once written), which is the right invariant and correctly refused the shortcut. What the moved branch does that the first import does not — pass the record's own url/branch, reportpreviousRepositoryId, advance the lineage — is asserted directly; the import itself is the same_import_github_revisionevery GitHub import already runs.7 new backend tests (unmoved, moved, older-member, upload, cross-owner 404, missing 404, unreadable head). 3 new frontend tests including "the panel re-reads its own history". Full backend suite green,
ruffclean,test_openapi_contract.pyupdated, frontend contract regenerated, 460 frontend tests + tsc + eslint clean.Unrelated, found while testing
github/demo-repositoryno longer resolves —git ls-remotereturns "Repository not found". That's the repository the marketing hero's demo panel walks through.