Skip to content
go-libfossil Today In History
Login

Today In History

This Day In History For 2027-10-20

1 Year Ago (more context)

2026-10-20
23:56
docs(sync): clarify exchange-local avoidance hint observations check-in: e500bfb4e3 user: [email protected] tags: feat/submanifest-reader, main, trunk
23:56
test(conformance): document commit hint conditional applicability check-in: 4436960f72 user: [email protected] tags: feat/submanifest-reader, main, trunk
23:56
test(conformance): verify exchange-local commit hint applicability check-in: 110f44ed85 user: [email protected] tags: feat/submanifest-reader, main, trunk
23:56
test(conformance): execute actual tree cycle and visit guards check-in: 16ce2b350e user: [email protected] tags: feat/submanifest-reader, main, trunk
23:56
refactor(conformance): bound canonical vector fixture helpers check-in: d3199d183b user: [email protected] tags: feat/submanifest-reader, main, trunk
23:56
test(conformance): pin canonical sparse rewrite contracts and vectors check-in: d444cbf081 user: [email protected] tags: feat/submanifest-reader, main, trunk
23:53
feat(sparse): add explicit public and CLI required-content recovery check-in: f57ca7de6a user: [email protected] tags: feat/submanifest-reader, main, trunk
23:51
feat(sparse): recover exact operation-selected payloads safely check-in: 221f0135ce user: [email protected] tags: feat/submanifest-reader, main, trunk
23:39
docs(sync): clarify exchange-local avoidance hint observations check-in: 8636a61a2e user: [email protected] tags: feat/submanifest-reader, main, trunk
23:38
fix(sync): withdraw empty-page sparse clone candidate cap check-in: 9448367581 user: [email protected] tags: feat/submanifest-reader, main, trunk
23:29
test(sync): prove prepared observer and cluster durability constraints check-in: 9eb8e3c090 user: [email protected] tags: feat/submanifest-reader, main, trunk
23:17
fix(sparse): preserve elided payloads across canonical recovery check-in: 40cdcdc837 user: [email protected] tags: feat/submanifest-reader, main, trunk
22:47
feat(sparse): recover exact required structural content atomically check-in: 7b478974f3 user: [email protected] tags: feat/submanifest-reader, main, trunk
22:36
fix(sync): bound sparse clone candidate enumeration check-in: 2be3110064 user: [email protected] tags: feat/submanifest-reader, main, trunk
21:38
perf(manifest): bound repair work by the linked batch (#455)

Propagate tags and apply scheduled leaf rechecks before each link transaction commits. Preserve sparse metadata repair, pretagged merge-parent rechecks, and rollback-safe retries. Tracked in #432. check-in: b38bf23f79 user: [email protected] tags: feat/submanifest-reader, main, trunk

21:00
fix(verify): audit leaves and parent ancestry (#454)

Use same-branch and arrival-order evidence for leaf validation, validate parent overrides, and match Fossil parent tokenization. Preserve sparse readiness and delta-tree scans within one verification snapshot. Tracked in #433. check-in: 35672aadc7 user: [email protected] tags: feat/submanifest-reader, main, trunk

19:07
fix(sync): preserve cleanup after a fatal clone refusal

Keep Fossil's mandatory operation-less second round without accepting any cleanup payload or clearing the refusal. Exercise dense and sparse refusal alongside the existing client compatibility cases. check-in: a453db484d user: [email protected] tags: feat/submanifest-reader, main, trunk

18:47
test(manifest): retain pending repairs across cancelled finalization

Exercise a caller-owned committed link, failed repair on cancellation and a normal candidate deferred until retry. Verify the same receive linker retains the original schedule and converges after retry. Update repair comments to describe the per-batch gates. leaf check-in: 72251e2dcd user: [email protected] tags: main, perf/tag-repair-batch, trunk

18:39
fix(manifest): match Fossil parent tag tokenization leaf check-in: 1b547f8cd6 user: [email protected] tags: fix/verify-leaf-rule, main, trunk
18:33
docs(conformance): record partial-tree lifecycle support and remaining limits check-in: b29428a4e2 user: [email protected] tags: feat/submanifest-reader, main, trunk
18:31
Merge commit 'bac111b' into feat/submanifest-reader check-in: e79a5cef6c user: [email protected] tags: feat/submanifest-reader, main, trunk
18:30
fix(manifest): scope sparse readiness proof to crosslink transactions check-in: 7ee2a8713d user: [email protected] tags: feat/submanifest-reader, main, trunk
18:26
test(verify): pin missing rows under either branch reading check-in: 9b5ad8d242 user: [email protected] tags: fix/verify-leaf-rule, main, trunk
18:23
test(manifest): cover sparse dependency arrival and cascade orders check-in: 61bc211295 user: [email protected] tags: feat/submanifest-reader, main, trunk
18:20
fix(verify): require independent leaf witnesses and surviving parent links check-in: 0cefd08b3f user: [email protected] tags: fix/verify-leaf-rule, main, trunk
18:14
Merge main into fix/verify-leaf-rule check-in: bc196580e4 user: [email protected] tags: fix/verify-leaf-rule, main, trunk
18:14
Merge main into batch tag repair, preserving unreleased changes check-in: ef382ed65e user: [email protected] tags: main, perf/tag-repair-batch, trunk
18:13
fix(verify): share snapshot-scoped sparse checkin readiness check-in: fe64b28b2d user: [email protected] tags: feat/submanifest-reader, main, trunk
18:10
Merge branch 'feat/submanifest-reader' into feat/sparse-tree-writer check-in: 08f1cd28ac user: [email protected] tags: feat/submanifest-reader, main, trunk
17:41
fix(manifest): preserve sparse ancestry and refuse incomplete file history check-in: ea3c1d6cc3 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:31
Merge public-content publication while preserving sparse carried files check-in: fb96ac5642 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:26
feat(manifest): derive sparse tree metadata with explicit completion gaps check-in: e96adae02f user: [email protected] tags: feat/submanifest-reader, main, trunk
17:26
fix(checkout): enumerate covered files over sparse tree stores check-in: 6878fdd664 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:20
Merge commit '45d80da' into feat/submanifest-reader check-in: eaa6316fd7 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:20
Merge commit 'f2cf3ed' into feat/submanifest-reader check-in: 1fe16a6bf5 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:20
Merge commit '80cfe22' into feat/submanifest-reader check-in: 4d78b267c8 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:20
test(conformance): require immediate error-only clone refusal check-in: 7bc35863dc user: [email protected] tags: feat/submanifest-reader, main, trunk
17:18
test(conformance): register sparse wire cases without hiding remaining gaps check-in: 743a561747 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:17
test(conformance): bound sparse protocol fixtures and document test scope check-in: bf7bc337f5 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:15
test(sync): cover failed cone fetch intent and retention counts check-in: 34adfc91d0 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:15
Merge commit '20b56c4' into feat/submanifest-reader check-in: 1f9f94350f user: [email protected] tags: feat/submanifest-reader, main, trunk
17:13
test(conformance): execute sparse sync protocol cases over loopback wire check-in: 233143abec user: [email protected] tags: feat/submanifest-reader, main, trunk
17:12
fix(sync): retain raw sparse provenance across rebuilds check-in: 5d727706dd user: [email protected] tags: feat/submanifest-reader, main, trunk
17:06
Merge branch 'feat/submanifest-reader' into feat/sparse-tree-writer check-in: 320629c0cb user: [email protected] tags: feat/submanifest-reader, main, trunk
17:06
fix(manifest): filter tree baselines before delta enumeration check-in: 9419a375f0 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:01
Merge sparse transfer with rebuild-safe compaction and schema guards check-in: a16e178c81 user: [email protected] tags: feat/submanifest-reader, main, trunk
17:00
Merge commit '00162b8' into feat/submanifest-reader check-in: e73fd9e276 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:58
test(conformance): distinguish subtree classification from writer support check-in: 440f271b07 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:58
test(sparse): preserve compaction provenance across rebuild and sync

Exercise mixed held and nested missing S siblings after clearing and rebuilding derived tables. Repeated compaction preserves holdings and elided identities; ordinary sync must not request the rebuilt elided artifacts. check-in: 29a11b0aa8 user: [email protected] tags: feat/submanifest-reader, main, trunk

16:56
Merge commit 'bc7af6d' into feat/submanifest-reader check-in: 6edcdc4e4d user: [email protected] tags: feat/submanifest-reader, main, trunk
16:54
fix(content): compact healthy partial trees using shared provenance

Use raw cone references while independently verifying held bytes. Preserve leaves and nonterminal paths so missing descendants keep their range proofs. Exercise missing S nodes, stale derived indexes, and cancellation after an observed demotion. check-in: 55b3ca7155 user: [email protected] tags: feat/submanifest-reader, main, trunk

16:54
feat(sync): fetch widened cone policy through an explicit peer check-in: 293300a722 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:51
fix(content): import raw sparse cone reference classification

Import content-only changes from ab9f98d845b8ff29fedea32ac65561959c564fd4, retaining optional forumpost table handling. check-in: 5220dbc3f3 user: [email protected] tags: feat/submanifest-reader, main, trunk

16:43
Merge commit 'e913b16' into feat/submanifest-reader check-in: a3f11a2baf user: [email protected] tags: feat/submanifest-reader, main, trunk
16:40
test(manifest): demonstrate sparse parent pin ambiguity check-in: 00784f9384 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:40
fix(sparse): infer partial tree provenance from raw artifacts check-in: d50ca873b3 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:34
test(manifest): expose sparse final-merge conflict check-in: 3975828d27 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:32
test(manifest): pin sparse boundary witness sizes check-in: 554db00b39 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:31
test(manifest): expose sparse canonical partition conflict check-in: 4312d7724d user: [email protected] tags: feat/submanifest-reader, main, trunk
16:27
style: format transfer flags and storage forwarding methods check-in: 5a53dae34f user: [email protected] tags: feat/submanifest-reader, main, trunk
16:25
Merge commit '575d5e3' into feat/submanifest-reader check-in: 0cf8b7a09b user: [email protected] tags: feat/submanifest-reader, main, trunk
16:24
Merge commit '0938087' into feat/sparse-transfer check-in: bed21ff045 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:21
test(conformance): register sparse compaction with explicit remaining gaps check-in: e7477e64f8 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:20
Merge commit 'f2c70bd' into feat/submanifest-reader check-in: e2829629bd user: [email protected] tags: feat/submanifest-reader, main, trunk
16:20
fix(content): tolerate repositories without the forum table check-in: 7a12c245df user: [email protected] tags: feat/submanifest-reader, main, trunk
16:19
test(content): prove compaction reader snapshots and local delta closure check-in: 6b1244bac2 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:18
refactor(repo): hold sparse compaction public surface pending review check-in: 84c5070f16 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:18
feat(sync): filter sparse receives without losing shared blobs or delta bases check-in: 9b60d9b691 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:17
fix(content): keep forum and cherry-pick dependencies dense check-in: 6fcada6c23 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:16
feat(repo): expose explicit sparse store compaction check-in: c18b7fba43 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:13
docs: keep feature notes above the unchanged v0.13 release check-in: ea92f1c237 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:13
test(sparse): prove compaction closures rollback and recovery check-in: 3fdb608c79 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:10
feat(sync): scope flat clone content and reject uncovered sparse origins check-in: 6a22fdc165 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:08
fix(content): retain structural phantoms and transitive delta bases check-in: 097e8fa156 user: [email protected] tags: feat/submanifest-reader, main, trunk
16:02
feat(content): compact sparse file holdings transactionally check-in: 91f8ae67bc user: [email protected] tags: feat/submanifest-reader, main, trunk
16:02
feat(sync): encode and validate sparse cone request pragmas check-in: 5c1fbd5ece user: [email protected] tags: feat/submanifest-reader, main, trunk
16:01
Merge main release fixes while preserving feature ticket coverage check-in: 67c2af8525 user: [email protected] tags: feat/submanifest-reader, main, trunk
15:58
Merge commit '8961b59' into feat/sparse-store check-in: dd6f1125ed user: [email protected] tags: feat/submanifest-reader, main, trunk
14:18
fix(manifest): publish carried file content in public check-ins check-in: 28430bfca2 user: [email protected] tags: feat/submanifest-reader, main, trunk
07:08
fix(manifest): recheck the parents of a check-in tagged before it is linked

A control artifact can write a check-in's branch row before the check-in is linked; that write schedules the check-in while it has no parents. When the check-in is linked later, in another transaction, its plink rows name parents nothing rechecks, so a parent on the same branch keeps a leaf row it no longer earns. Applying leaf rechecks per link transaction made this common in a clone, which links each received artifact in its own transaction: a clone of fossil.fossil ended with 1435 leaves instead of fossil's 1426.

Linking a check-in that already carries a branch row now schedules it, and with it the parents it names. A check-in with no branch row is left alone, as fossil leaves it (#426). TestReparent's relink keeps propagated branch rows, so it now gives c2 the verdict a rebuild does.

Tracked in #432. check-in: 789434c556 user: [email protected] tags: main, perf/tag-repair-batch, trunk

06:29
test(manifest): probe arrival order against a rebuild

TestArrivalOrderMatchesRebuild builds a random history per seed, delivers its blobs to a fresh repository in random order and rounds, crosslinking after each, and compares tags and leaves with a rebuild. It runs only when LIBFOSSIL_ARRIVAL_PROBE names a seed count. Without reparents every seed must match; with them it reports the seeds that differ, the divergence documented on ReparentCheckins.

Tracked in #432. check-in: 4f3f1669e6 user: [email protected] tags: main, perf/tag-repair-batch, trunk

05:45
docs(manifest): state where a reparent diverges from a rebuild

A reparent propagates from the new parent, which fossil's manifest_reparent_checkin does not, and never removes the tags inherited from the old parent, which fossil does not either; fossil's own rebuild is order-dependent there. Say both in ReparentCheckins, and rename the reparent test so it no longer claims full convergence. Note in the CHANGELOG that a failed sync no longer sweeps before it returns, so artifacts committed outside a phantom fill wait for the next crosslink.

Tracked in #432. check-in: 9ff7dea0b5 user: [email protected] tags: main, perf/tag-repair-batch, trunk

04:47
fix(manifest): apply leaf rechecks in the transaction that links the batch

Each link transaction now runs the whole repair gate before it commits: the reparent pass, tag propagation from the parents it linked, and the leaf rechecks it scheduled. Fossil's manifest_crosslink_end runs the reparent pass and leaf_do_pending_checks inside the transaction that linked the check-ins, so a crash can never leave a committed check-in without its leaf row; this does the same. The schedule records whether a transaction linked anything, so one that linked nothing skips the gate.

The gate at the end of a sweep or a receive is gone. Finalize repairs only what a caller linked through LinkStored in a transaction it opened itself rather than through ReceiveLinker.WithTx, which is all that can still leave work on the schedule.

Tracked in #432. check-in: 8c00d632b7 user: [email protected] tags: main, perf/tag-repair-batch, trunk

04:31 • Edit [ae2704ef94]: Add tag "v0.13.0" with note "Release v0.13.0

The libfossil binary now has a checkout-free interface for apps that keep version history in a stock Fossil repository. Its JSON shapes and exit statuses are a stable contract, documented in docs/site/content/docs/cli-embedding.md: - repo snapshot commits one file's bytes onto trunk without a checkout. Identical bytes are a no-op that prints the tip. Concurrent snapshot processes build one linear trunk. - repo log --path, repo cat --at and repo diff --json read a file's history, content and differences. - repo new accepts the repository path as -R, refuses an existing file, and names a missing parent directory. Exit statuses: 0 success, 1 failure, 2 not found, 80 usage error.

Behavior changes to check when upgrading: - Times read back from the repository round to the millisecond as SQLite does. They had been truncated, often 1ms before the check-in's D card. - Check-ins, tags and branches record their time to the millisecond, as fossil does. - log, cat and diff match a PATH as fossil does: normalized, and compared under the repository's case-sensitive setting (off by default on macOS and Windows). - Opening a repository applies its pragmas in a fixed order, busy_timeout first. - Update keeps uncommitted changes, and vfile.mtime is recorded and trusted, as fossil does. - Ticket artifacts are applied with fossil's optional ticket columns, so a rebuild of fossil's own repository succeeds and its ticket tables match fossil rebuild.

See CHANGELOG.md for the full list.". artifact: 432ca36218 user: [email protected]

04:31
chore(release): v0.13.0 changelog (#458) check-in: ae2704ef94 user: [email protected] tags: main, trunk, v0.13.0
03:36
chore(release): v0.13.0 changelog leaf check-in: 530ef65683 user: [email protected] tags: chore/release-v0.13.0, main, trunk
03:15
fix(manifest): honor fossil's optional ticket columns (#456)

* test(manifest): cover ticket schemas without fossil's optional columns

Fossil treats the ticket table, ticket.tkt_ctime, the ticketchng table, ticketchng.tkt_rid and ticketchng.tkt_user as optional. Each schema here must derive the rows fossil rebuild derives; all fail today.

* fix(manifest): honor fossil's optional ticket columns

Port ticket_insert and ticket_rebuild_entry's schema probes from src/tkt.c: the ticket table, tkt_ctime, the ticketchng table, tkt_rid and tkt_user are optional, a change row is written only when it has a field or bookkeeping column to fill, fields stored in both tables are copied from the ticket row, and baseline columns record the assigning rid. Rebuilding fossil's own repository failed on its missing tkt_user.

* docs(changelog): note optional ticket columns fix

* test(manifest): pin ticket append to an unset field, baselines and shared columns

The corpus now appends to a field no artifact set, to a field with a baseline column, and to a field stored in both tables, so the comparison against fossil rebuild covers each branch of the append path. check-in: 1f46e25556 user: [email protected] tags: main, trunk

03:13
refactor(sync): drop the closing gate a cascade no longer needs

Each phantom-fill cascade batch already reparents, propagates and applies its leaf rechecks before it commits, so a sync's closing crosslink and the repair after a failed round owed the cascades nothing. Remove the cascade count that kept them running: CrosslinkAfterCascades folds into CrosslinkContext, the sync client and handler stop counting cascaded links, and the handler stores files through storeReceivedFile. The closing gate now runs only when its own sweep linked something, for the sweep's leaf rechecks and the reparent pass.

Tracked in #432. check-in: 1ed447441a user: [email protected] tags: main, perf/tag-repair-batch, trunk

03:11
Merge branch 'main' into fix/verify-leaf-rule check-in: 0762218b66 user: [email protected] tags: fix/verify-leaf-rule, main, trunk
03:01
Merge remote-tracking branch 'origin/main' into feat/submanifest-reader

# Conflicts: # internal/checkout/vfile.go check-in: 741864259c user: [email protected] tags: feat/submanifest-reader, main, trunk

02:58
fix(cli): match PATH as fossil does; run pragmas in a fixed order (#457)

* fix(cli): match PATH as fossil does; run pragmas in a fixed order

log --path, cat --at and diff drop a leading ./, a trailing / and doubled or /./ separators, and compare names with the repository's case-sensitive setting, fossil's platform default when unset. Not found stays exit 2, where fossil exits 1; the docs now say so. SettingBoolean moves to internal/repo, shared by sync and checkout.

Opening a repository runs every pragma in a fixed order, not only busy_timeout first.

Tracked in #451

* feat(cli): document and pin repo new for embedding apps

repo new takes the path from -R as the other embedding commands do, refuses a missing parent directory with a message naming it, and is documented in the embedding contract with its output and exit statuses. Tests pin each behaviour and that stock fossil opens the result.

Tracked in #451

* docs(cli): say how ../x, absolute paths and the global case-sensitive setting behave

Tracked in #451 check-in: 8de2ae751d user: [email protected] tags: main, trunk

02:48
fix(checkout): restore the database/sql import the merge dropped check-in: ab7f1cde7b user: [email protected] tags: feat/submanifest-reader, main, trunk
02:45
Merge branch 'feat/submanifest-reader' into feat/sparse-store check-in: e4f56e44a9 user: [email protected] tags: feat/submanifest-reader, main, trunk
02:40
Merge branch 'fix/revert-swap-chain' into feat/submanifest-reader

# Conflicts: # internal/checkout/revert.go check-in: 32155296d0 user: [email protected] tags: feat/submanifest-reader, main, trunk

02:37
Merge branch 'fix/symlink-write-paths' into feat/submanifest-reader check-in: 79679cc3fa user: [email protected] tags: feat/submanifest-reader, main, trunk
02:09
Merge branch 'docs/repin-00' into feat/submanifest-reader check-in: d868c1b189 user: [email protected] tags: feat/submanifest-reader, main, trunk
02:08
conformance: re-pin the three drafts to their -00 names

zit check-in 68a3f76cb7 renames the artifact-format, repo-state and sync-protocol drafts from -01 to -00 in their headers, cross-references and reference entries, and retitles each Changes appendix "Changes in This Revision". No normative text changed and no section number moved.

The pinned copies take zit's file names, the requirement tables pin the new hashes, and the comments, tests and docs that cited the -01 drafts cite the -00 ones. The refresh script copies every draft under its own name. The sparse-cone copy is re-pinned to d497c2432f, whose text is unchanged. Coverage counts are identical before and after. check-in: 245a0ed306 user: [email protected] tags: feat/submanifest-reader, main, trunk

01:49
fix(cli): match PATH as fossil does; run pragmas in a fixed order

log --path, cat --at and diff drop a leading ./, a trailing / and doubled or /./ separators, and compare names with the repository's case-sensitive setting, fossil's platform default when unset. Not found stays exit 2, where fossil exits 1; the docs now say so. SettingBoolean moves to internal/repo, shared by sync and checkout.

Opening a repository runs every pragma in a fixed order, not only busy_timeout first.

Tracked in #451 leaf check-in: 430dd5ec70 user: [email protected] tags: fix/cli-path-matching, trunk

01:43
docs(changelog): note Verify's two leaf readings and reparented plink check-in: ee2234ee3f user: [email protected] tags: fix/verify-leaf-rule, main, trunk
01:42
test(stash): fossil and go both refuse to merge a repointed symlink check-in: aec658f5a9 user: [email protected] tags: feat/submanifest-reader, main, trunk
01:42
fix(stash): do not merge a changed symlink, as fossil's stash apply does

Where a symlink was stashed or is now on disk, Apply writes the stashed file only when both are links and the link still holds the baseline. Otherwise it leaves the file and its row alone and reports it, as fossil's stash_apply prints "Cannot merge symlink" and counts a conflict. Apply and Pop now return the files they did not merge; Pop still drops the entry, as fossil's does. check-in: 2ee5684bf3 user: [email protected] tags: feat/submanifest-reader, main, trunk

01:40
test(stash): pop over a changed symlink does not merge it (red) check-in: d19a7ecca7 user: [email protected] tags: feat/submanifest-reader, main, trunk
01:40
fix(verify): accept fossil's leaf tables and reparented plink

leaf.Audit reads same-branch both as the draft does (active branch rows, the main-branch setting) and as fossil 2.28's leaf_check does (any branch row, the literal trunk). A row is stale only when both read a child as same-branch, and missing only when neither does, so Verify accepts the tables fossil writes when main-branch is not trunk or a branch tag was cancelled, and a go-built table after main-branch changes.

checkPlink no longer reports a P-card parent missing from plink when the check-in carries a parent tag, which replaces those rows in fossil. check-in: a6a1038b60 user: [email protected] tags: fix/verify-leaf-rule, main, trunk

01:36
Merge remote-tracking branch 'origin/main' into feat/submanifest-reader

# Conflicts: # CHANGELOG.md # internal/fsltype/julian_test.go check-in: 63f78ed893 user: [email protected] tags: feat/submanifest-reader, main, trunk

01:31
Merge remote-tracking branch 'origin/main' into fix/verify-leaf-rule check-in: 7c834d64ec user: [email protected] tags: fix/verify-leaf-rule, main, trunk
01:30
Merge branch 'docs/drafts-without-errata' into feat/submanifest-reader check-in: 27732942f1 user: [email protected] tags: feat/submanifest-reader, main, trunk
01:30
test: read isLink as an integer under both drivers check-in: 179069251f user: [email protected] tags: feat/submanifest-reader, main, trunk
01:30
feat(cli): checkout-free snapshot, per-path log, cat --at and diff --json (#453)

* feat(cli): checkout-free snapshot, per-path log, cat --at and diff --json

repo snapshot commits one file's bytes onto trunk with no checkout, a no-op when they equal the tip. repo log --path lists the check-ins that changed a path, repo cat --at reads a file as a version holds it, and repo diff --json A B [PATH] diffs two versions. Exit 2 means not found. A snapshot re-checks the check-in stamp inside its write transaction and retries, so concurrent processes build one linear trunk.

Tracked in #451

* test(cli): cover log across a rename; order exit statuses in the docs

Tracked in #451

* fix(db): convert Julian days to the millisecond SQLite gives

log --json printed most check-in times 1ms before their D card: db.julianToTime truncated where SQLite's date.c rounds with (sqlite3_int64)(r*86400000.0+0.5). fsltype.MillisFromJulianDay now does exactly that, JulianToTime and ScanTime use it, and ScanTime rounds the time.Time ncruces hands back to the millisecond as well.

* fix(cli): print usage errors on stderr and pin their exit status 80

The documented status was right for the binary; go run turns it into 1. Usage text went to stdout, so an embedder reading stdout saw it on a failure. The doc now says which status a measurement under go run shows, and a test pins 80 for an unknown flag, a missing flag or argument and an unknown subcommand.

* fix(cli): refuse a snapshot path holding a control byte or a reserved name

validateRepoPath now applies fossil's own rules for a new file name: file_is_simple_pathname in strict form (deck.StrictPathname), no byte below 0x20, and file_is_reserved_name, whose existing port in deck is exported as IsReservedName. Each refusal exits 1 and names the reason.

* fix(cli): diff A B PATH matches fossil's PATH rules

A PATH in neither version printed [] and exited 0; fossil diff --from A --to B fails with "not found". It now exits 2 (not found), and PATH also matches a directory, as fossil's file_dir_match does. The test runs fossil on the same repository as the oracle.

* fix(cli): refuse a snapshot into a repository with no main-branch check-in

When the main branch resolved to nothing, snapshot took the repository for empty and committed a second root beside the existing history. It now treats only a repository with no check-ins as empty, and otherwise fails at exit 1 naming the branch.

* test(cli): compare log across a rename with fossil finfo

The rename test built its history through manifest.Checkin and checked our own idea of the result. It now builds the history with the fossil binary and compares repo log with fossil finfo on the same repository: both stop a name's history at the rename. The doc tells an embedder how to follow a file across renames, and where log differs from finfo.

* fix(db): set busy_timeout before any other pragma on open

The drivers build the DSN's _pragma parameters from a map and run them in that order, so journal_mode or foreign_keys often ran before busy_timeout. An open while another process held a lock then failed at once with "database is locked" instead of waiting: one cause of TestSnapshotConcurrentProcesses failing under -tags test_ncruces.

* fix(cli): hold the write lock from snapshot's read of the tip to its commit

Under -tags test_ncruces, TestSnapshotConcurrentProcesses failed 8 of 20 runs. Besides the open-time lock error fixed in db, a snapshot read the tip's manifest outside any transaction while another process's check-in re-deltaed it, and failed with a hash mismatch. A snapshot now runs in one bound write transaction from the read of the tip to its commit, so no other check-in can land in between; the optimistic retry loop it replaces is gone. check-in: 90345545d3 user: [email protected] tags: main, trunk

01:30
Merge branch 'feat/submanifest-reader' into fix/revert-swap-chain check-in: c7a321a35d user: [email protected] tags: feat/submanifest-reader, main, trunk
00:51
test(conformance): drop the erratum files; the draft text is the authority

zit applied every erratum in its draft text and retired docs/rfcs/erratum/ at check-in 62a7d1bb3f. Each draft records its corrections in its own Changes appendix, so the suite stops pinning and reading erratum files: the "# erratum" pin lines, the parser branch that accepted them and conformance/rfcs/erratum/ are removed, and comments that named an erratum file cite the draft section instead.

The artifact-format, repo-state, sync-protocol and delta-format drafts are byte-identical at 62a7d1bb3f. The sub-manifest draft is re-pinned; it differs only in its expiry date, reflow, and the dropped pointer to the erratum files. The sparse-cone draft is re-pinned to the 19 October 2026 revision on zit's horizon-rfc branch (0acb5e185c, its merge of 62a7d1bb3f): section 3.6 is removed and section 3.4 states the literal prefix rule once, so SC-3.6-1 becomes SC-3.4-3 (a metacharacter is a literal character, never expanded, and the member may be refused), covered by the same case, renamed sparsecone.3.4.metachar. The refresh script copies the -01 texts to their -01 names and takes the horizon-rfc drafts from a second checkout. check-in: 3e1f791160 user: [email protected] tags: feat/submanifest-reader, main, trunk

00:25
docs(changelog): sparse store classification and verification check-in: 242b5f3d9e user: [email protected] tags: feat/submanifest-reader, main, trunk
00:25
test(manifest,verify): unit tests for commit and verify over a sparse store check-in: c935561cfc user: [email protected] tags: feat/submanifest-reader, main, trunk
00:25
test(conformance): zit checks the sparse store

zit clones go-libfossil's flat history through a cone, and both sides must report the same number of elided phantoms over the same cone. Each side then commits over its sparse store and pushes to a dense store of the other. The commit carries no R card, and the receiver holds the whole check-in. check-in: 0a63c3b22f user: [email protected] tags: feat/submanifest-reader, main, trunk

00:25
test(conformance): one sparse-store fixture for every origin check-in: a76ce676f6 user: [email protected] tags: feat/submanifest-reader, main, trunk
00:25
test(conformance): cover the sparse store's step-3 requirements

Cases elide out-of-cone blobs from a dense clone, as a cone-scoped clone would leave the store. They check the three absence classes, the client and server sync filters, recomputation on a cone change, loss of the cone (unreadable, or dropped by fossil rebuild, after which fossil's pull heals the store), verify and rebuild counts, R-card omission and skipping, a commit over elided subtrees pushed to a dense peer, widening, hybrid histories, and delta bases.

Holding out-of-cone sub-manifest nodes is recorded as a deviation from §5.1. zit holds them too, because a tree that cannot be enumerated never links.

A checkout's record names the phantom for a file that neither cone covers, so a checkout opens over a sparse store. check-in: b907b41650 user: [email protected] tags: feat/submanifest-reader, main, trunk

00:25
feat(sync): never request a sparse store's elided phantoms

The client's phantom load and the server's request_phantoms skip elided phantoms (draft-fossil-sparse-cone-00 §5.2). A dense store classifies nothing and behaves as before. Repo.StoreCone and Repo.SetStoreCone expose the store cone. check-in: 37f15485b4 user: [email protected] tags: feat/submanifest-reader, main, trunk

00:25
feat(manifest,verify): commit over a sparse store, and count absences

A commit over a store with a store cone leaves out the R card (draft-fossil-sparse-cone-00 §4.3). It refers to out-of-cone files the store lacks by hash alone (§5.3). VerifyRCard skips over a sparse store, and skips a manifest that has no R card, since an absent R card is not damage.

verify.Report gains Phantoms (transit) and Elided. Neither is an Issue, so a store complete within its cone verifies OK (§5.2). Rebuild keeps the store cone and reports the same counts. check-in: cd98ba38cb user: [email protected] tags: feat/submanifest-reader, main, trunk

00:25
feat(content): store cone and the three absence classes of the sparse store

The store cone (draft-fossil-sparse-cone-00 §5) is kept in a storecone table that exists only while a cone is set. fossil rebuild drops tables it does not know, so losing the cone reads as dense and the store heals toward dense (§5.2). A cone that does not parse also reads as dense.

LoadAbsences sorts every phantom into transit, shunned or elided by zit's rules. A phantom is elided when F cards name it only outside the store cone and no held delta uses it as a base. check-in: 524c749185 user: [email protected] tags: feat/submanifest-reader, main, trunk