Commit Graph
2 Commits
Author SHA1 Message Date
claude ddb829d701 fix(client): make our credential helper the only one the repo consults
Live QA against the beta forge failed its first push with 'Failed to
authenticate user' while the config held a valid token. Cause: credential.helper
is a list accumulated across system/global/repo config, and this machine has
osxkeychain (Xcode gitconfig) plus store (~/.gitconfig). A stale entry for the
forge host answered before our helper.

The same list is a token leak in the other direction: git calls approve on
every helper after a successful auth, so 'store' writes the forge token into
~/.git-credentials in plaintext -- undoing the 0600 config and the
no-token-in-URL rule. Confirmed accidentally during QA when a verification
clone with a URL-embedded token re-created exactly that entry.

Fix: set an empty credential.helper first (git reads that as 'forget the
inherited list'), then add ours -- in install_credential_helper and in the
git clone inside get.

2 regression tests, one of which drives 'git credential fill' against a
poisoned outer helper. 143 tests.
2026-08-23 11:29:44 -04:00
claude 9e3201a296 feat(client): snapshot backups, restore points, scoped bulk pull
Two modes per linked folder. 'mirror' keeps today's behaviour for a plain
folder that add turned into a repo. 'snapshot' is new and is for a folder
that already had a git history: nothing is ever committed on the user's
behalf, and instead each pass builds a commit object from the working tree
via a scratch index + commit-tree and pushes it to
refs/granthi-backup/<device>/<ts>. HEAD, the index and every file stay
exactly as the user left them, so uncommitted, unmerged, half-finished work
leaves the machine with a timestamp to restore from.

Verified on the beta forge (Gitea 1.27.2) that a custom ref namespace is
accepted, readable via ls-remote, and absent from the branch list.

Also: retention (all for 24h, hourly for 7d, daily beyond; unparseable
timestamps kept), snapshots/restore commands, restore never writing over the
working tree, get --all bounded by what the forge grants, list <pattern>,
.gitignore seeding, an add size guard, and a persisted device_id.

141 tests (was 108).
2026-08-23 11:22:20 -04:00