feat(worktree): keep a per-worktree merge flow that scripts read
Every worktree can carry a deterministic merge flow in <git-dir>/pkgmgr/flow.yml (never committed, gone with the worktree): pull lists the refs merged into the branch, in order, before a gate, deploy or merge; push lists the branches the finished branch is merged into, in order, each then pushed by the operator.
- pkgmgr worktree flow [PATH] [--json] shows it; flow set (--pull REF.. | --no-pull) (--push BRANCH.. | --no-push) replaces both lists atomically (0600 temp file, os.replace, pkgmgr/ of mode 0700); flow clear removes it. JSON: worktree, git_dir, branch, flow_branch, pull, push, source (file, none, invalid), warnings.
- pkgmgr worktree up gains repeatable --pull/--push; without them pull is the base and push its local branch (origin/main gives main).
- pkgmgr branch tree carries "flow": {pull, push, source} or null on every item with a worktree, read from the linked worktree's metadata dir without running git inside the worktree; the Agent Orchestrator shows it.
The file and the arguments may come from an agent: every entry must equal its git check-ref-format --branch output (scan mode, cwd /) and must not start with -; the reader opens pkgmgr/ and flow.yml without following links, non-blocking, refuses anything but a regular file, caps at 64 KiB, uses yaml.safe_load, rejects unknown keys, wrong types and bool versions, and never raises into callers: a bad file reads as source invalid with empty lists and a warning.
Tests: 30 new (unit and integration on real repositories), unit suite 500 OK, integration 254 with the two known sandbox signing errors of test_publish_integration only.
🎯 Fix: 92 %
💥 Break: 4 %
💸 Cost: 97 %
⏱️ Time: 93 %
🛡️ Security: 100 %
🏆 Score: 98
🚦 Gate: ✅ 90/5, cost and time <= 100, security 100 %
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
4c8b137449
commit
7fb229688b
12 files changed
+1196
-10
No files matched your search
@@ -74,7 +74,10 @@ versioning features it can drive **end-to-end workflows**:
|
||||
|
||||
| Command | Does |
|
||||
| --- | --- |
|
||||
| `pkgmgr worktree up <branch> [--base REF] [--path DIR]` | Checks the branch out under `<directories.worktrees>/<host>/<owner>/<repo>/<branch>` or at `--path`, assigns a free slot and runs the pinned `worktree-init` hook |
|
||||
| `pkgmgr worktree up <branch> [--base REF] [--path DIR] [--pull REF ...] [--push BRANCH ...]` | Checks the branch out under `<directories.worktrees>/<host>/<owner>/<repo>/<branch>` or at `--path`, assigns a free slot, records the merge flow and runs the pinned `worktree-init` hook |
|
||||
| `pkgmgr worktree flow [PATH] [--json]` | Shows the merge flow of the worktree at `PATH` (default: `.`) |
|
||||
| `pkgmgr worktree flow set [PATH] (--pull REF ... \| --no-pull) (--push BRANCH ... \| --no-push) [--json]` | Replaces both lists of the merge flow |
|
||||
| `pkgmgr worktree flow clear [PATH] [--json]` | Removes the merge flow |
|
||||
| `pkgmgr worktree cleanup [--apply]` | Removes clean worktrees whose commits are merged or pushed: pinned `worktree-fini` hook, compose stack, checkout; the branch stays |
|
||||
| `pkgmgr branch cleanup [--apply]` | Removes merged branches that no worktree holds, locally and on the remotes |
|
||||
| `pkgmgr branch tree [--format json\|yaml] [--output FILE]` | Writes every managed repository's branches and worktrees with their cleanup state, without fetching |
|
||||
@@ -108,6 +111,46 @@ Every cleanup is a dry run until `--apply`, and `--json` prints the plan for
|
||||
other tools. The [agent skills](https://github.com/kevinveenbirkenbach/skills)
|
||||
wrap these commands; see [AGENTS.md](AGENTS.md) for the split.
|
||||
|
||||
#### Merge flow
|
||||
|
||||
Every worktree can carry a merge flow that scripts and skills read: `pull`
|
||||
lists the refs merged into the branch, in order, before a gate, deploy or
|
||||
merge; `push` lists the branches the branch is merged into, in order, when it
|
||||
is finished, each then pushed by the operator. It lives in
|
||||
`pkgmgr/flow.yml` inside the worktree's own git directory (`.git` of the main
|
||||
worktree, `<common>/worktrees/<id>` of a linked one), so it is never committed
|
||||
and goes with the worktree:
|
||||
|
||||
```yaml
|
||||
version: 1
|
||||
branch: feature/x
|
||||
pull:
|
||||
- origin/main
|
||||
- store-i18n
|
||||
push:
|
||||
- feature/iam-profile-rbac
|
||||
- production
|
||||
```
|
||||
|
||||
`branch` is the branch the flow was set on; another current branch shows as a
|
||||
warning. `worktree up` records `--pull` and `--push`; without them pull is
|
||||
the base the worktree came from and push that base's local branch
|
||||
(`origin/main` gives `main`). `flow set` needs each list or
|
||||
its `--no-pull`/`--no-push`, and writes atomically into a `pkgmgr/` of mode
|
||||
0700. Every entry must pass `git check-ref-format --branch` and must not start
|
||||
with `-`; a remote-tracking name such as `origin/main` passes. An invalid name
|
||||
exits 2 and writes nothing. A flow file that is a symbolic link, no regular
|
||||
file, larger than 64 KiB or malformed reads as `invalid`, with empty lists and
|
||||
a warning, and is never followed.
|
||||
|
||||
`flow --json` prints `worktree` and `git_dir` (absolute paths), `branch` (the
|
||||
current branch, `null` when detached), `flow_branch` (the file's `branch`),
|
||||
`pull`, `push`, `source` (`file`, `none` or `invalid`) and `warnings`; it
|
||||
exits 0 also without a flow, 2 when `PATH` is not a git worktree. In
|
||||
`pkgmgr branch tree` every item carries `flow`: `{"pull", "push", "source"}`,
|
||||
or `null` without a worktree or a flow; flow warnings join the repository's
|
||||
`warnings`.
|
||||
|
||||
---
|
||||
|
||||
## Architecture & Setup Map 🗺️
|
||||
|
||||
Reference in new issue
Block a user