magus v0.4.3 is out. See what's new
¶ View generated markdown
5 min read

magus-vcs

Listing and conflict resolution that knows what is generated

Synopsis

magus vcs <ls-files|resolve|checkpoint|merge-driver> [flags]

Description

Version-control operations that read the workspace's output declarations, so generated files and hand-written sources are treated differently.

ls-files lists dirty paths and stages nothing; you stage what it lists. By default it lists tracked, modified or deleted declared sources that no other live job holds and that are not already staged. Every other dirty path is left out by a group, and stderr names each group with the flag that lists it: --include-untracked, --include-generated (outputs a dirty source explains), --include-unexplained (outputs nothing here explains, with the drift code), --include-unclaimed (paths no target declares, and the ones magus maintains), --include-held (paths another live job writes) and --include-staged. A backend that keeps no such state refuses the flag: only git stages, and jj has no untracked files.

Positional patterns and --exclude take write-path patterns (a literal path, a directory, or a glob with * and **), read from the current directory and matched the same way on every backend. --project scopes to the files a project owns. Patterns only narrow; a pattern that matches no dirty path is said on stderr. Stage the listing with:

magus vcs ls-files -o name | git add --pathspec-from-file=-

resolve settles an in-progress merge, rebase, or cherry-pick. It classifies every conflicted path at once, regenerates once instead of once per file, settles the files one side deleted (which no VCS invokes a merge driver for), and stages everything the regeneration touched so a following commit or rebase --continue does not refuse on a dirty tree. Conflicts in files magus does not generate are reported and left alone. Pass --against <ref> to merge that ref first and settle what it conflicts with; add --dry-run to see the classification and have the merge backed out again.

--hook <name> is how git runs resolve itself. magus init --vcs git writes the pre-merge-commit, pre-commit, post-commit, post-rewrite and post-applypatch hooks beside the merge driver, each calling resolve once the merge, cherry-pick, revert, rebase or am has the whole tree; magus doctor reports a driver whose hooks are missing. It regenerates only the projects whose declared sources or outputs the operation changed, plus what the merge driver recorded, and stages the result: into the commit git is about to make, or, for a clean merge, in place of git's own commit, which git then leaves to you as "git commit". After a rebase or a clean cherry-pick the commits already exist, so it stages and prints the amend; it never amends. A failed regeneration stops a pending commit and prints the command that does it.

merge-driver is the per-file driver git and hg invoke during a merge. You do not run it by hand; it is wired per clone, because a driver registration cannot be committed. That is also why a forge reports conflicts your own clone would settle silently, and why resolve exists as the bulk counterpart.

checkpoint prints the identity of the working state right now - head revision, branch, whether the tree is dirty, and a digest of the uncommitted patch. Record one when you hand a piece of work out, so a later reader knows what that work was looking at. By default it RESOLVES AND RECORDS and never MINTS: no tag, no stash, no ref, no file, nothing changed anywhere, so a checkpoint nobody keeps has cost nothing. Feed the revision to anything that takes one; compare two digests to learn whether two workers saw the same uncommitted tree, which the revision alone cannot say.

--preserve is the one thing that mints. An identity says whether two trees match; it cannot rebuild either one. --preserve additionally captures the uncommitted work - tracked edits and untracked files alike - and prints a handle that gets it back, using each backend's own mechanism: a commit under refs/magus/preserved for git, a kept shelf for Mercurial, a commit Sapling keeps hidden, and for Jujutsu the working-copy commit it already holds. The working copy is untouched either way.

Retention differs per backend. On git and Mercurial a capture is dropped at 30 days, by two passes that cover each other's gap: every preserve prunes, which bounds a repository nothing schedules against, and the server's prune-preserved job prunes on its own, which reaches a repository preserved once and never again. That job is a no-op with no server running, so on a machine that runs none the standalone spelling is magus server prune-preserved.

Sapling drops nothing either way: magus mints a hidden commit there, and no Sapling command removes one without discarding the working copy, so those stay until you remove them. List them with sl log --hidden -r "desc('magus preserved working copy')". Jujutsu mints nothing, so nothing accumulates.

resolve works on git, Mercurial and Jujutsu. Only --against is git-only: merge the base in yourself on the others, then run resolve.

vcs ls-files options

--exclude pattern
Leave out paths this write-path pattern covers; repeatable or comma-separated
--include-generated
Also list declared outputs a dirty source in this change explains
--include-held
Also list paths another live job in this checkout writes
--include-staged
Also list paths whose whole change is already staged; git only
--include-unclaimed
Also list paths no target declares, and the ones magus maintains itself
--include-unexplained
Also list declared outputs no source change here explains
--include-untracked
Also list untracked files; refused on jj, which has none
--project project
List only the files this project owns; repeatable or comma-separated

vcs resolve options

--against ref
Merge this ref first, then settle what it conflicts with

vcs checkpoint options

--preserve
Also capture the uncommitted work and print a handle that restores it

Subcommands

ls-files
List the dirty paths a commit of this change wants; stages nothing
resolve
Settle an in-progress merge's conflicted generated files, then regenerate once
checkpoint
Print the working state's identity, for recording what a lease was handed; writes nothing unless --preserve
merge-driver
The per-file merge driver git and hg invoke; you do not run this by hand

Examples

Stage the dirty sources and nothing else

magus vcs ls-files -o name | git add --pathspec-from-file=-

List one subtree's changes, with the outputs they regenerated

magus vcs ls-files --include-generated 'internal/guard/**'

List a new file too

magus vcs ls-files --include-untracked --project libs/xdg

Settle a conflicted merge

magus vcs resolve

Merge the base in and settle it in one step

magus vcs resolve --against origin/main

Record what a lease was handed

magus vcs checkpoint

The one citable token, for a ledger cell

magus vcs checkpoint -o name

Capture the uncommitted work too, before something risky

magus vcs checkpoint --preserve

See Also

magus(1), magus-ls(1), magus-describe(1), magus-where(1), magus-run(1), magus-affected(1), magus-x(1), magus-clean(1), magus-shell(1), magus-query(1), magus-refs(1), magus-explain(1), magus-path(1), magus-graph(1), magus-diff(1), magus-session(1), magus-job(1), magus-notes(1), magus-queue(1), magus-watch(1), magus-events(1), magus-server(1), magus-broker(1), magus-mcp(1), magus-status(1), magus-buzz(1), magus-spell(1), magus-agent(1), magus-init(1), magus-doctor(1), magus-config(1), magus-completion(1), magus-man(1), magus-self(1), magus-version(1)

generatedinternal/commands/registry.goclimagus vcsgitmergeconflictsgenerated filesstagingls-files
Last updated (61fd39a7)
Earlier changes on this page (7)

Full history ↗ · Blame source ↗

Glossary

Workspace

The magus root directory that owns a set of projects and shared config; the unit magus operates over. Workspace in full.

Project

A directory magus recognizes as a unit of work (it has a magusfile); the unit of caching, scheduling, and dependency tracking. Project in full.

Target

A named operation (build, test, ...) you invoke with magus run <target>; it may compose a spell's tool-native operations and depend on other targets. Target in full.

Op

A single tool-native command a target composes (long form: operation); the middle of the work hierarchy (Spell to Op to Target). Op in full.

Spell

A language/runtime adapter (e.g. go, md) that maps generic targets onto a toolchain's real commands. Spell in full.

Buzz

The language magusfiles are written in (the .buzz engine). Buzz in full.

Affected

The set of projects touched by a change; magus affected <target> runs a target only over them. Affected in full.

Broker

The per-user background process that holds this host's capacity: the machine budget every run claims slots from, and the shared services runs keep warm. A run starts it on demand; broker: off in magus.yaml runs without one. Broker in full.

CI

An ordinary target you compose yourself with ctx.needs; magus does not hardcode its stages. It is the anchor magus affected ci keys off, and ci strips the rw charm. CI in full.

MAGUS.md

The committed routing index at a workspace root, regenerated from the knowledge graph: it lists every node and points at the exact query for a given question, so it is the entry point an agent reads first. MAGUS.md in full.

Agent

A model working through an agent host such as Claude Code, Codex, Cursor or OpenCode. magus treats an agent as one more caller of its CLI, MCP tools and console, held to the same checks as a person. Agent in full.

Session

An agent host's conversation, by the id the host delivers to its hooks. magus never mints one: a record with no session is unattributed, and the OS user it carries says whose account ran it. Session in full.

Job

The unit of delegated work, and one row of the job store: what an orchestrating agent handed out, with its goal, the checkpoint it was cut against, the paths it may write or must not touch, and the one check it runs. A job's holder is either a session, for work an orchestrator handed out, or the daemon, for its own maintenance. The store records; the agent guard is what reads those facts back when grading a write. Job in full.

Run

One target executing under one magus invocation, such as magus run test web or magus affected ci. A run keeps its captured output behind an output reference. Every magus run is a run whether or not any job asked for it; see Job for how the two relate. Run in full.

Lease

The grant a holder takes on a job: the write and read paths that job declared, enforced in the checkout that took it with magus job exec. A job is the piece of work; a lease is permission over it. Lease in full.

Conventions

This page uses none of the site's convention markers. The full set is on the conventions page.