Artifact 07e848c1698e230d028ce7f09a0653c875c96730063a376cc2f2c62e50a43fc3:
- File
conformance/repostate_gaps_test.go
— part of check-in
[cba2d0c823]
at
2026-10-13 11:05:50
on branch main
— feat(resolve): resolve checkout-relative names and branch-type requests (#409)
* feat(resolve): resolve checkout-relative names and branch-type requests
Checkout.ResolveVersion resolves current, prev/previous and next relative to the open checkout, after tip and before the other forms, as fossil's symbolic_name_to_rid does; a keyword that names nothing falls through. Repo.ResolveBranchStart is the branch-type request: it resolves a name and walks back to the first check-in of its branch. Section 8.3 walks back from every result; fossil only from tag:NAME and plain names, and this follows the draft.
The repostate.8.3 checkout and branch-type cases run against the new entry points, with new cases for a keyword shadowing a tag, prev at a root, an untyped ckout, root:current and a branch-type hash. Tracked in #386.
* fix(resolve): match check-ins only for branch-type requests, merge via checkout
A branch-type request is rewritten to a check-in request (repo-state-01 Section 8.3), so a technote tagged with the branch name cannot answer it. A checkout with no recorded version resolves the ordinary forms, and merge resolves its version through the open checkout. Tracked in #386.
* fix(resolve): wrap a long test line (user: [email protected], size: 2299) [annotate] [blame] [check-ins using]
package conformance import "testing" // repostateGaps marks the repository-state cases go-libfossil is known to // fail, by case ID, grouped by the code at fault, each with the issue // tracking its fix. var repostateGaps = map[string]string{ // Crosslink deferral (internal/manifest/crosslink.go missingCheckinRefs). "repostate.4.2.root-absent-file": "#406", } // repostateDeviations marks the cases where go-libfossil follows fossil(1) // rather than the draft text, by case ID. var repostateDeviations = map[string]string{ "repostate.7.3.parentless-untagged": parentlessDeviation, // verify.Rebuild now derives leaves through the crosslink sweep, so it shares // the same branch-aware leaf rule and the same ยง7.3 deviation. "repostate.7.3.parentless-untagged.rebuild": parentlessDeviation, // The same check-in seen from Section 7.3's crosslink trigger: linking it // does not recheck it, as fossil's does not. "repostate.7.3.recheck-lone-untagged": parentlessDeviation, // An untagged child of a tagged check-in: Section 7.3 rechecks it and // its parent when it is linked. "repostate.7.3.recheck-untagged-child": untaggedChildDeviation, "repostate.7.3.recheck-untagged-child.rebuild": untaggedChildDeviation, } const untaggedChildDeviation = "follows fossil(1): a check-in with a parent but no branch " + "tag is never rechecked, so it is no leaf and its parent keeps its verdict, where " + "Section 7.3 rechecks every crosslinked check-in and its parents; widening the " + "candidates changed the leaf table of a real fossil-authored repository (the " + "libfossil corpus)" const parentlessDeviation = "follows fossil(1): an untagged parentless check-in is " + "never a leaf, where Section 7.3 makes every check-in without a same-branch " + "child one (the section's informative note records fossil's behavior)" // TestRepoStateGapKeys checks that every marked case exists. func TestRepoStateGapKeys(t *testing.T) { ids := map[string]bool{} for _, c := range repostateSuiteCases() { ids[c.ID] = true } for id := range repostateGaps { if !ids[id] { t.Errorf("repostateGaps names %s, which is not a case", id) } } for id := range repostateDeviations { if !ids[id] { t.Errorf("repostateDeviations names %s, which is not a case", id) } } }