Artifact a6f5c5e41440ceb49cba178832cfc6ff83b956278fb92412718f0373b08e85f7:
- File
internal/manifest/private_file_test.go
— part of check-in
[6d239246d0]
at
2026-10-19 02:08:32
on branch feat/submanifest-reader
— fix(manifest): make every file blob a public check-in names public
A public check-in could reuse content first stored privately, say by syncing a private branch, and leave it in the private table. Sync never sends private blobs to a peer without private access, so that peer got a check-in whose file stayed a phantom and could not be checked out.
storeFileBlobs now calls content.MakePublic on each file blob inside the check-in's transaction, as fossil's commit calls content_make_public for each F card (checkin.c). The blob is already queued in unsent, so the next push carries it. The sub-manifest writer already does this for trees.
Tracked in #439. (user: [email protected], size: 1495) [annotate] [blame] [check-ins using] [more...]
package manifest import ( "testing" "github.com/danmestas/go-libfossil/db" "github.com/danmestas/go-libfossil/internal/blob" "github.com/danmestas/go-libfossil/internal/content" ) // A public check-in makes every file blob it names public, as fossil's commit // does (checkin.c, content_make_public per F card): content first stored // privately, say by a private branch, would otherwise never reach a peer // without private access, leaving the check-in's file a phantom there. The // test stores the content privately, commits it publicly, and checks the // blob left the private table and is queued for the next push. func TestCheckinMakesReusedPrivateFileBlobPublic(t *testing.T) { r := sha3Repo(t) data := []byte("shared with a private branch\n") if err := r.WithTx(func(tx *db.Tx) error { rid, _, err := blob.Store(tx, data) if err != nil { return err } return content.MakePrivate(tx, int64(rid)) }); err != nil { t.Fatal(err) } _, d := commit(t, r, CheckinOpts{ Files: []File{{Name: "f.txt", Content: data}}, Comment: "public", }) if len(d.F) != 1 { t.Fatalf("F cards = %d, want 1", len(d.F)) } if isPrivate(t, r, d.F[0].UUID) { t.Fatal("file blob stays private under a public check-in") } rid, _ := blob.Exists(r.DB(), d.F[0].UUID) var n int if err := r.DB().QueryRow("SELECT count(*) FROM unsent WHERE rid=?", rid).Scan(&n); err != nil { t.Fatal(err) } if n != 1 { t.Fatal("file blob made public but not queued for the next push") } }