Repository navigation
tether 0.1.0b4
Pre-releaseSecurity
git: a manifest'spathmust be absolute and outside the checkout; git
runs no fsmonitor, hook,ext::transport or implicit bare repository, and
ignores an inheritedGIT_DIR,GIT_WORK_TREE,GIT_INDEX_FILEor
GIT_CONFIG_*.git: a committedremotemust name a configured remote; a URL goes in
.tether/secrets.toml([objects."<key>"] remote).import:[import] queryis read from.tether/secrets.toml, not
tether.toml, and runs as one read-only statement.dolt: credentials come only from the server's[uris."mysql://host:port"]
entry in.tether/secrets.toml(password_env/user_envmove there);
$DOLT_PASSWORDwent to any host a manifest named.- Object keys may not contain
\or a drive letter, and are checked when a
manifest is read. .tether/secrets.toml,workspace.tomlandops.jsonlare refused while
jj or git tracks them, with the command that untracks them. The committed
.tether/.gitignorewas all that kept them out, so a cloned
secrets.tomlnaminggit_pathran that program ontether status.- git 2.38 is the minimum version, checked by the VCS adapter and the
git
backend; an older git ignoressafe.bareRepositorywithout a word. - Another live checkout's
workspace.tomlorops.jsonlthat the VCS tracks
there is skipped, with a warning naming the checkout: a shipped op log could
makegcrelease pins as this clone's. openchecks again whether the VCS tracksworkspace.tomlwhenever the
file has changed, so a long-livedReporefuses one that a pull or commit
put under version control afterfind.
Added
-
ObjectBackend.fork,promoteandmergetakeexpected=, the head the
caller reviewed (orABSENT): the ref moves only from there, else
RefMovedErrorand nothing moves. Backends without the keyword work as
before; the engine passes the heads its plans reviewed. -
tether.plan.REQUIRED_PRECONDITIONSper command, and aworkspace_bookmark
precondition: the checkout's bookmark asworkspace.tomland the VCS see it. -
The conformance suite checks conditional forks,
PROMOTE,MERGE,
ancestor_ofand opening an older recorded state. -
gc --release-foreign(Repo.gc(release_foreign=)): also release
unreferenced pins this clone did not create. -
icechunk:allow_httpandforce_path_stylein.tether/secrets.toml
(per URI prefix or object) for an S3-compatible server such as SeaweedFS
or MinIO; without themadd --createcould not reach one. -
Capability.CONDITIONAL_REFdeclares that a backend's ref moves honour
expected; conformance fails a backend that claims it and ignores it. -
new --sharedadopts a peer's uncommitted writes when they build on the
bookmark's pin, instead of asking for--discard.
Changed
-
Partial success (an
undo,repair,upgradeorforget-workspacethat
could not do everything) exits 3; 2 is Click's usage error. -
--helpkeeps bracketed text such as[experimental];add --kindlists
each kind with its maturity. -
A plan must carry the preconditions its command requires; one saved by an
older tether, or edited, is refused as stale.commit,new,restore,
promote,drop,gcandrepairplans bind to the checkout that made
them, andcommit,restore,promoteanddropplans to its bookmark;
import,upgradeandforget-workspaceplans bind to no checkout. -
promotelands committed states only (tether commituncommitted writes
first). Merges run before fast-forwards, which are held when a merge does
not land; the trunk moves to the commit the plan reviewed. -
restorechecks the head of every branch it would reset, deferred forks
included, wants--discardfor uncommitted writes, and refuses a head it
cannot read. -
undoreverses the newest operation only and refuses one it cannot undo
rather than reaching past it;tether undo IDrestores only the
workspace.tomlfields that entry changed. Thenewandgcadropruns
are its steps ((step of ID)intether ops) and cannot be undone alone. -
new,restoreand the first writableopenhold the repository lock
while they check and fork, and fork only onto the head the plan saw. -
Without
fcntl(Windows), writing commands are refused;status,verify,
diff,log,opsandgc --dry-runwork. -
gcanddroprelease only pins this clone created (recorded in
tether-pinned.jsonlbeside the repository lock, seeded from the op logs).
Any other unreferenced pin is kept as informationalkeep-pinuntil it is
fetched or--release-foreignis passed;GcReport.kept_pinsandgc --jsonlist them. -
jj 0.43 is the minimum version; an older one is refused.
-
jj and git run with tether's own colour and pager settings, whatever the
user's config says; tether tracks its own files by name, and its revsets
use no name an alias can redefine. Colour forced on,all()aliased or
auto-tracking off had corrupted commit ids, made empty commits, or shrunk
the historygcwalks. -
file,icechunk,lance,delta: every spelling of a local path --
/p,/p/,file:///p, a path through a symlinked parent such as macOS's
/tmp-- is one store to pin ids, listings andgc. New pins of an
object registered under another spelling get new ids. -
neon: pins are unprotected unlessprotected_pins = true; Free has no
protected branches, and paid plans allow a few. -
The dataset format is version 5: run
tether upgradeonce on a 0.1.0b3
dataset. It gives the stores intether-touched.jsonland
tether-created.jsonltheir new identities, stores listings again under
their new names, records Lance (branch_id), Neon (commit_xid) and
directory (symlinks) states in the new form where the data is unchanged,
and makes DuckLake paths absolute. 0.1.0b3 refuses a version 5 dataset,
so clones on the two releases cannot take turns. -
Saved plans are format 3, with a digest binding their actions and context
to their preconditions; re-run a plan saved in format 1 or 2. -
gcandpromoteprint what they applied along with the failures, and
exit 3 when part of the work was done. -
jj calls keep only your identity, signing, snapshot and git settings, and
yourimmutable_heads()with the revset aliases it names. -
A new file of yours that jj has not snapshotted stays in the change it was
made in when tether moves the working copy. -
Every
openfollows the checkout's current bookmark; on Windows a default
openis read-only.
Removed
- The
lakefsbackend,tether add --repository/--prefix,LakeFSHandle
and thelakefsextra.
Fixed
-
Delta
historyanddiffattached the wrong commit to each version below
the head. -
Lance states off
maincarry the branch id, so a state from a re-created
branch verifies as missing instead of opening another branch's data. -
tether diffwith no arguments compares against jj's@-, not the working
copy commit. -
file:allow_httpand the other HTTP client options work on S3; symlinks
to directories and dangling ones count by their target; the racy-timestamp
guard covers every timestamp granularity. -
tether statuslabels an unreadable objecterror, reports the rest and
exits 1 instead of aborting. -
tether init --jsonprints only JSON. -
Two
--sharedcheckouts materializing one lazy fork could throw the first
one's write away. -
Undoing an older
newafter a commit on its branch deleted the branch, for
pin = "record"the only copy of that state; it now needs--discard, and
the workspace no longer rolls back to that time's bookmark. Undoing an older
addmoved the checkout tomain, so the next write went to the store's
main. -
Two
undos after adroprevived the abandoned commit. -
jj: undoing a commit other commits were built on rewrote them; refused now
(jj backoutreverts in place). -
promotelanded uncommitted writes and moved the trunk to a commit
recording an older state; a conflicted merge left its fast-forwards landed;
a saved plan applied on another bookmark moved the trunk there; the reset
after a merge discarded a concurrent write. -
A long-lived
Repo's writableopenignored anewanother process ran
since it was constructed. -
newkept the previous bookmark's snapshot cache, sostatusand
commit --no-snapshotused the old branch's head under the new bookmark. -
AWS profile or role credentials were never refreshed (now five minutes
before expiry), and two prefixes of one bucket with different credential
rules shared the first's. -
The locks were re-entrant per
Repo, not per thread; a second thread could
leave thatRepounable to lock again. -
jj:
dropfrom a bookmark whose working copy had edits planned no leave and
leftworkspace.tomlnaming the dropped bookmark. -
gccounts every live checkout's working-tree manifests and the pins of
running or interrupted operations as references;--prune-bookmarkskeeps
every branch a live checkout works on or has pending. -
gcanddroprefuse while jj reports a conflicted bookmark or a
.tether/conflict no later commit resolved, andpromotewhile its trunk
is conflicted;statusandcommitname a conflicted bookmark instead of
calling it gone. -
commitraises when the new commit's tree lacks a manifest (a dataset under
an ignored directory made an empty commitstatuscalled clean). -
git: a hook-refused
git commitleft the manifests staged; the index is
reset. -
jj: the history walk reads every side of a conflicted commit, so
gc
counts the pins each side names. -
file: a local path holding#or?was cut short there, and
add --createon afile://URI made a strayfile:directory. -
A saved
dropplan applies only in the checkout that made it, and only
while that checkout is still on (or off) the bookmark as the VCS sees it. -
A checkout writes its workspace id on first open, so a plan saved in a
fresh clone or worktree applies there. -
dropcloses its journal entry when the store half fails. -
An op-log entry appended after a torn line is no longer lost with it.
-
--from-planrefuses--dry-runand--plan;commit --from-plan p.json --dry-runcommitted. -
An
[objects."<key>"]entry in.tether/secrets.tomlreaches the store
add --createmakes and, once the object is removed, the store
gc --delete-storesreclaims; both used the default endpoint and ambient
credentials. -
icechunk: aprofileorrole_arnentry hands Icechunk a refresh
callback, so a handle held past the role's expiry keeps writing; only new
opens used to get fresh keys. -
gcnever releases a pin some manifest names, whichever spelling of the
store that manifest uses; one store named two ways lost pinsHEAD
referenced.gc --delete-storesalso matches an indexed store by the
identity its locator has now, so a created store a manifest still names is
no longer deleted. -
gc(a dry run too),gc --delete-storesandverify --all-historyskip,
with a note, the manifests history holds of a backend tether no longer
has; a dataset that ever held a lakeFS object failed them even after
remove. Their pins still count as references. -
promotelanded uncommitted writes aftertether undoor
commit --no-vcs: it checks forks against the bookmark's commit. -
tether undo IDof an oldernew -bsent the checkout tomain; it
reverts only the fields nothing has changed since. -
Lance's conditional fork replaced a peer's branch, and git's moved a
branch checked out in another worktree;repair's refork is conditional. -
git:
status.showUntrackedFiles = nohid new manifests fromcommit. -
The pin index claimed pins other clones had made, and kept released ones.
-
A writable
openre-read every manifest; only changed files are parsed. -
A plain
statushid the errors astatus --snapshothad cached. -
tether diffon a jj merge working copy showed every object as added. -
file: client options in another spelling (AWS_ALLOW_HTTP) panicked, and
a non-string value (timeout = 5) raised. -
Threads resolving one AWS profile or role made one STS call each.
-
git:
abandonleft a manifest the abandoned commit had added deleted in
the worktree, so the next commit deleted it. -
gclisted one failure when a ref of one name (a bookmark's branch) failed
in two stores; each failure now names its object.
Experimental
neon:addrequiresdatabaseandrole; connection URIs name their
endpoint; busy answers (423, 429, 503) are retried with backoff; a compute
restart no longer reads as a write.dolt: a merge with conflicts or constraint violations raises
MergeConflictand writes nothing.iceberg: tables with no snapshot yet are accepted; requires
pyiceberg >= 0.11.ducklake: a relativemetadatapath is stored absolute.ducklake: a leading~inmetadataordata_pathis expanded (it was
stored as<cwd>/~/...), and a baresqlite:orduckdb:metadata path
is stored absolute too.neon: objects on one branch fingerprinted at once each created its
endpoint; Neon allows one read-write endpoint per branch.