Repository navigation
v0.27.0
safegit adopts the framework's machine-output envelope: --json now emits the strictcli envelope as the sole stdout document with a command's own data as its payload, and machine mode no longer forces --quiet. The four history rewrites mint real effects, so a dry-run preview finally lists what it would do. Three dry-run bugs are fixed: a preview no longer writes under .git/, and it no longer refuses a dirty working tree.
Context
The dependency on the CLI framework moved off a local workspace and onto the
released strictcli go v0.32.0, which publishes the machine-mode envelope API
this work is written against. That release also reworded the refusal a
consequential command gives when stdin is not a terminal, so safegit's pinned
copy of that string is updated to match.
This is the version rlsbl's scrub path requires: rlsbl pins
SAFEGIT_MIN_VERSION = 0.27.0 for the rewrite journal and the JSONL hash
remapping it drives from it.
Breaking
--jsonis now the framework's machine mode, and its output shape changed. stdout carries exactly one document -- the strictcli envelope (interface_version,app,command,exit_code,payload,dry_run,preview,preview_error,diagnostics) -- and a command's own data is itspayloadmember rather than the whole stream.--jsonis no longer a safegit flag (it is framework-owned and recognized anywhere in argv), it no longer implies--quiet(the envelope is exempt from quiet, so--json --quietemits the complete document), a failing command answers with its exit code and stderr instead of a{"error": ...}object, and a dry run's recorded effects ride the envelope'spreviewmember instead of a would-do log printed after the JSON. Every payload-producing command declares a JSON Schema the framework validates at emission and--dump-schemapublishes verbatim. Anything parsing safegit's JSON must read the payload.- The refusal a consequential command gives when there is no terminal is reworded.
scrub file,scrub match,scrub runandauthor rewriterefused a non-interactive run witherror: stdin is not interactive; pass --approve-consequential to confirm; against the released strictcli v0.32.0 that line now readserror: stdin is not interactive; a consequential command must be confirmed at a terminal. The behaviour is unchanged -- the four commands still refuse without a terminal, and--approve-consequentialstill consents -- but a script or hook matching on the old text will no longer recognize it. safegit's own refusals for the conditions the framework cannot see (doctor --uninstall, abackup backupto a public remote) are unchanged and still name their consent flag.
Fixes
- Dry-run scrub no longer writes to disk or refuses a dirty working tree.
safegit --dry-run scrub file|match|runcreated.git/safegit/(config.json, the operation log, lock directories) before previewing anything, and refused to run at all when the working tree had uncommitted changes -- the state a preview is most useful in. A preview now leaves the repository byte-for-byte untouched and runs on a dirty tree; every execute path still requires a clean one. - A dry-run commit no longer writes to disk, and a half-initialized repository repairs itself.
safegit --dry-run commitcreated its per-invocation temporary index under.git/safegit/tmp/and left that directory behind, which made the repository read as initialized whileconfig.jsonwas absent -- after which every safegit command there failed withreading config.json: no such file or directoryuntil.git/safegitwas deleted by hand. A preview now stages into an OS temporary directory and touches nothing under.git/, and a.git/safegitwithoutconfig.jsonis completed on the next executing command instead of being trusted as complete. - A dry-run
author rewriteworks on a dirty working tree.safegit --dry-run author rewriterefused when the working tree had uncommitted changes -- exactly the state a preview is wanted in -- because the clean-tree requirement ran before the preview branch. The preview now runs on a dirty tree; an executing rewrite still requires a clean one. - A dry-run history rewrite finally says what it would do, and both renderings agree.
scrub file,scrub match,scrub runandauthor rewriteminted no effects, so--dry-runprinted the would-do log's header over an empty body -- reading as "this would change nothing" about a preview of an irreversible rewrite. The rewrite is now recorded through the effects handle, so the log lists the ref move and the reflog/repack/prune cleanup that follows it (and the same records ride the envelope'spreviewin machine mode). The human and machine outputs are also one computation now:estimated_commitsused to exist only in the machine branch, and the human "in N objects" count was a different denominator from the machine field it read like.scrub matchreports both, asobjects_matchedandobjects_scanned.