| <!-- SPDX-License-Identifier: Apache-2.0 |
| https://www.apache.org/licenses/LICENSE-2.0 --> |
| |
| <!-- START doctoc generated TOC please keep comment here to allow auto update --> |
| <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> |
| |
| - [`magpie-vcs`](#magpie-vcs) |
| - [Prerequisites](#prerequisites) |
| - [Configuration](#configuration) |
| - [Why](#why) |
| - [The abstraction](#the-abstraction) |
| - [Backends](#backends) |
| - [Adding a backend](#adding-a-backend) |
| - [How to use](#how-to-use) |
| |
| <!-- END doctoc generated TOC please keep comment here to allow auto update --> |
| |
| <!-- SPDX-License-Identifier: Apache-2.0 |
| https://www.apache.org/licenses/LICENSE-2.0 --> |
| |
| # `magpie-vcs` |
| |
| **Capability:** contract:source-control |
| |
| **Kind:** implementation |
| |
| **Vendor:** Git |
| |
| Runnable implementation of the **source-control (VCS) capability** |
| documented in |
| [`tools/github/source-control.md`](../github/source-control.md). It |
| extracts the abstraction the dev-loop skills assume — branch, stage, |
| commit, diff, log, fetch, push, working-tree reset — out of inline |
| `git` calls into one backend-dispatching CLI. |
| |
| A skill (or a person) runs the **abstract** operation: |
| |
| ```bash |
| uv run --project tools/vcs magpie-vcs -C <upstream> diff --base main |
| uv run --project tools/vcs magpie-vcs -C <upstream> log --grep ISSUE-123 |
| ``` |
| |
| The active backend is **detected** from the working copy (or forced |
| with `--backend` / `$MAGPIE_VCS`), so the same command works whatever |
| VCS the project enables under *Tools enabled → Source control*. |
| |
| ## Prerequisites |
| |
| - **Runtime:** Python 3.11+ run via `uv`; stdlib-only (no runtime |
| dependencies). The `dev` group pulls `pytest`, `ruff`, `mypy`. |
| - **CLIs:** Depends on the active backend — the tool shells out to the |
| underlying VCS binary. `git` for the complete backend; `hg` / `svn` are |
| detected but their bindings are not yet implemented. |
| - **Credentials / auth:** None of its own; write operations (`fetch`, |
| `push`) inherit whatever auth the underlying VCS/remote needs. |
| - **Network:** Local for read and local-write operations; `fetch` / `push` |
| reach the project's remote (e.g. GitHub) over the network. |
| |
| ## Configuration |
| |
| The active backend is detected from the working copy or forced with |
| `--backend` / `$MAGPIE_VCS`. Skills get the checkout path from |
| `<project-config>/user.md` (or the resolved user config) and the expected |
| source-control backend from `<project-config>/project.md` *Tools enabled* |
| entries. Backend-specific adopter knobs belong in the relevant |
| `*-config.md` file rather than in this tool. |
| |
| ## Why |
| |
| Before this tool the skills hard-coded `git …` inline. PR #609 added |
| the capability *contract* (`source-control.md`) and pointed each |
| git-using skill at it; this tool is the *implementation* of that |
| contract — the single place a non-Git VCS bridge plugs in, instead of |
| editing every skill. |
| |
| ## The abstraction |
| |
| `VCSBackend` is the abstract interface; each operation maps to the |
| *What the skills require* table in `source-control.md`: |
| |
| | Operation | CLI | Read/Write | |
| |---|---|---| |
| | Detect backend | `detect`, `backends`, `root` | read | |
| | Working-tree status | `status`, `clean` | read | |
| | Current branch | `branch` | read | |
| | Show changes | `diff [--base REF] [--cached] [paths…]` | read | |
| | History read | `log [-n N] [--grep P] [--author A] [--since S] [paths…]` | read | |
| | Create line of work | `new-branch <name>` | write | |
| | Switch ref | `switch <ref>` | write | |
| | Stage | `stage <paths…>` | write | |
| | Commit | `commit -m <msg>` | write | |
| | Sync from forge | `fetch [remote] [ref]` | write | |
| | Publish | `push [-u] <remote> <ref>` | write | |
| | Reset working copy | `reset-worktree` | write | |
| |
| Write operations stay gated on explicit user confirmation **in the |
| calling skill**, exactly as the tracker write paths are — the tool does |
| not add its own prompt. |
| |
| ## Backends |
| |
| | Backend | Status | Notes | |
| |---|---|---| |
| | `git` | **complete** | GitHub's native VCS; the default binding | |
| | `hg` (Mercurial) | **complete** | Mercurial VCS support | |
| | `svn` (Subversion) | extension point | detected; centralized model (`distributed = False`) → [#602](https://github.com/apache/magpie/issues/602) | |
| |
| Detection is real for every backend (so `magpie-vcs detect` reports the |
| working copy's VCS correctly); the non-Git/non-Hg backends raise an actionable |
| `VCSError` naming their tracking issue until the full binding lands. |
| |
| ### Adding a backend |
| |
| A VCS bridge (e.g. #602 Subversion) implements the full binding by |
| replacing that backend's `_UnimplementedBackend` base with a concrete |
| `VCSBackend` subclass — `detect()`, the read operations, the write |
| |
| operations — and nothing else changes: detection, dispatch, the CLI, |
| and every skill that calls `magpie-vcs` pick it up automatically. |
| |
| ## How to use |
| |
| ```bash |
| # run the tests |
| uv run --project tools/vcs --group dev pytest |
| |
| # in a skill / shell, against an upstream checkout |
| uv run --project tools/vcs magpie-vcs -C ~/code/foo detect |
| uv run --project tools/vcs magpie-vcs -C ~/code/foo status |
| ``` |
| |
| Exit codes: `0` success, `1` for `clean` when the tree is dirty, `2` |
| for any `VCSError` (unknown/unsupported backend, failed command). |