Tags: codingapi/git-workspace
Tags
Fix cache-key collision and verify false-success; add tests + CI (0.4.0) Cache-key collision (P0): cache_key() slugified the URL with a lossy regex, so distinct URLs could map to the same mirror cache (.../a/b.git vs .../a-b.git) and ensure_cache() would silently hand the second source the first repo's objects. The key now appends a short sha256 of the exact URL (same URL still shares one cache); ensure_cache() additionally checks `git remote get-url origin` before reusing a cache, and load_config() rejects an explicit `cache:` key shared across two different URLs. Existing caches use the old names, so upgrading re-clones once (old dirs reclaimed by `clean --all`). verify false-success (P1): verify only compared HEAD when a lock SHA existed, so a deleted lock or a dirty *writable* source still passed. It now fails closed: the lock must exist and be version 1, config and lock must agree (shared config_lock_mismatches() helper, also used by `sync --locked` so the rules can't drift), every source must be materialized at its locked SHA with a clean worktree, and read-only sources must also be filesystem-locked. Tests + CI (P1): new tests/test_git_workspace.py (stdlib unittest, drives the real CLI against throwaway local repos) covers locked-sync under upstream drift, url/revision/source-set mismatch, absolute + symlink path escape, the cache collision, verify's dirty/missing-lock/not-in-lock cases, read-only drift, nested sources and idempotency. New GitHub Actions workflow runs the suite on ubuntu/macos/windows. __version__ bumped to 0.4.0; READMEs updated; .gitignore covers __pycache__. Co-Authored-By: Claude <noreply@anthropic.com>
Fix three P0 safety/correctness issues; add verify command (0.3.0) P0 #1 — assembly paths can no longer escape the workspace. load_config now rejects absolute paths and, after resolving both the target and the workspace root, requires the target to live inside the root (this also defeats symlinked/junction ancestors). cmd_clean re-checks containment before any removal as defense in depth. P0 #2 — `sync --locked` now truly reproduces the lock. It validates that the config's source set, url and revision all match the lock (hard error otherwise), then checks out the *locked* SHA verbatim — a floating revision such as `main` advancing upstream no longer breaks it — and it does not rewrite the lock file. The old resolved-vs-lock comparison is removed. P0 #3 — a modified read-only source is now rejected. materialize_source checks dirtiness for read-only sources even when HEAD already matches the target, so local edits can no longer silently survive a sync. New `verify` command gates CI: every source must be materialized with HEAD matching the lock, and read-only sources must be clean and locked; exits non-zero on any problem. Docs updated to the strict --locked semantics and an honest statement of the read-only guarantee (anti-accident guardrail, not a security boundary). __version__ bumped to 0.3.0. Co-Authored-By: Claude <noreply@anthropic.com>
tag-pinned installs, self-update, bilingual README; bump to 0.2.1
- install.sh / install.ps1 standalone mode installs the latest release tag
(git ls-remote --sort=-v:refname), with default-branch fallback
- Add 'git-workspace update': self-upgrade the installed CLI to the latest
upstream release tag; refuses inside a git checkout (use git pull there)
- README restructured (features / usage / uninstall / commands / core
components & how it works / contributing), split into README.md (English)
and README.zh-CN.md (中文) with a language switcher
- Bump __version__ to 0.2.1
Co-Authored-By: Claude <noreply@anthropic.com>
publish as standalone CLI: rename to git-workspace, English, init com… …mand, installers - Rename CLI `workspace` -> `git-workspace`; config workspace.yaml -> git-workspace.yaml; lock -> git-workspace.lock.yaml - Ship the previous live config as example.yaml / example.lock.yaml - Translate all code, Makefile, README and the hook to English - Resolve the workspace root by walking up from the CWD (enables global install) - Add `init` (scaffold config + commit-protection hooks) and `version` subcommands, -V/--version, and an examples epilog in -h - Guard is now lenient: never blocks commits on a missing/empty/broken config - Add cross-platform installers: install.sh (Linux/macOS/Git-Bash) and install.ps1 (native Windows) - Add CLAUDE.md Co-Authored-By: Claude <noreply@anthropic.com>