blob: 22f4747f03ebe782d47a321fb4a9c003fcb75b68 [file] [view]
<!-- 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).