fix: surface store sync failures + add secrets sync (EGB-1230, EGB-1231)
EGB-1230: `cmd_pull` synced the store with `git pull >/dev/null 2>&1` under `set -euo pipefail`. A store that couldn't fast-forward killed the script at that line with git's exit 128 and nothing on stdout or stderr — a banner, no restored files, no reason, and invisible in a pipeline. The sync now routes through `_store_sync_pull`, which guards the pull, captures git's output as the diagnosis, and dies naming the store path and `secrets sync`. It is now `--ff-only` to match the push path, so a plain pull can no longer manufacture a merge commit in the store. EGB-1231: once a store diverged there was no way out — push demanded a fast-forward and pointed at pull, which couldn't fast-forward either, so the advice looped and recovery meant hand-running git next to encrypted blobs. Adds `secrets sync`: fetch, stash, rebase onto the remote, restore the stash, then a confirmation-gated push of local commits (`--yes` to skip the prompt, `--dry-run` to report only). Non-destructive by construction — no merge, no force-push, no `reset --hard`, no `stash drop`; a rebase conflict names the conflicting files and leaves the store exactly as found. `secrets which` gains a `remote:` line reporting ahead/behind/dirty, and push's dead-end message now points at `sync`. test/sync.bats: 25 new tests. Full suite 353/353 green. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BrUoYuUMoTj91rzV4vxGPB
This commit is contained in:
parent
2558ea3c23
commit
dd6a025fa0
6 changed files with 681 additions and 8 deletions
41
CHANGELOG.md
41
CHANGELOG.md
|
|
@ -5,6 +5,47 @@ All notable changes to this project will be documented in this file.
|
|||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
||||
and this project adheres to a four-digit MAJOR.MINOR.PATCH.MICRO version scheme.
|
||||
|
||||
## [0.7.6.0] - 2026-09-08
|
||||
|
||||
### Added
|
||||
|
||||
- **`secrets sync` — reconcile a diverged store (EGB-1231)** — the store is a
|
||||
git repo, and once a clone was both ahead and behind its remote the CLI had
|
||||
no way out: `push` demanded a fast-forward and pointed at `pull`, which
|
||||
could not fast-forward either, so the advice looped and recovery meant
|
||||
hand-running git next to a directory of encrypted blobs. `secrets sync`
|
||||
fetches, stashes uncommitted blob edits, rebases local commits onto the
|
||||
remote, restores the stash, and then asks before publishing local commits to
|
||||
the shared store. `--yes` skips the prompt (scripts/CI); `--dry-run` reports
|
||||
ahead/behind/dirty and what would happen, changing nothing. Deliberately
|
||||
non-destructive: no merge, no force-push, no `reset --hard`, no `stash
|
||||
drop`. A rebase conflict aborts, restores the stash, names the conflicting
|
||||
files, and leaves the store exactly as found.
|
||||
- **Store state in `secrets which` (EGB-1231)** — a new `remote:` line reports
|
||||
the store's `ahead N, behind N, N modified` (or `up to date`) against its
|
||||
upstream, with a `(run: secrets sync)` hint when there is anything to
|
||||
reconcile. Offline-safe (reports against the last fetch, never reaches the
|
||||
network) and silent for a local-only store or one with no upstream.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **`secrets pull` no longer fails silently when the store can't sync
|
||||
(EGB-1230)** — the store sync was `git pull >/dev/null 2>&1` under `set -euo
|
||||
pipefail`, so a store that could not fast-forward killed the script at that
|
||||
line with git's exit 128 and *nothing* on stdout or stderr. The user saw a
|
||||
banner, no restored files, and no reason — indistinguishable from a project
|
||||
with nothing to pull, and easy to lose entirely in a pipeline. The sync is
|
||||
now guarded, git's output is captured and surfaced as the diagnosis, and the
|
||||
error names the store path and points at `secrets sync`.
|
||||
|
||||
### Changed
|
||||
|
||||
- **`secrets pull`'s store sync is now fast-forward only**, matching the push
|
||||
path. A plain `git pull` could quietly manufacture a merge commit in the
|
||||
store; divergence is now resolved in exactly one place — `secrets sync`.
|
||||
- **The push path's dead-end advice** ("Run 'secrets pull' first, then retry
|
||||
push") now points at `secrets sync` and includes git's own output.
|
||||
|
||||
## [0.7.5.0] - 2026-06-24
|
||||
|
||||
### Added
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue