OverviewFilesCommitsIssuesDocsReleasesPeers

pgh commits / d101e5a

0.1.131: add `pgh repo set-head <name> <branch>`
Fronts pear-git-v3's repo-set-head RPC, which sets a repo's DEFAULT BRANCH fleet-wide. HEAD was per-backend until now — a symbolic ref, unmodelable in the ref→hash view — so each node repaired it with a master→main→first heuristic and nodes disagreed. 4 of 142 repos did on the live pair, and the public saw whichever backend the load balancer hit. HEAD is replicated now, but a repo whose nodes already disagree gets seeded by whichever writer reconciles first, so this command makes it a decision rather than a race. Takes `main` or `refs/heads/main`. Admin, and must run on the tracker owner — the daemon reports both conditions rather than failing quietly. Version bumped despite the bump-at-publish convention agreed for pear-git-v3: the guard hook is right that pgh is a file: workspace package other apps bundle, so shipping new bytes under an unchanged version causes BUILD_SKEW. That convention does not extend here. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
d101e5a1fda3d95c83e66a666a5050b302ae5bf6
by plankatron <fleeky@gmail.com> · 2026-07-30T19:57:46.000Z

Changed files (2) +16 -1

lib/commands/repo.js +15 -0
……@@ -27,6 +27,10 @@ export const usage = `pgh repo — browse repos served by the daemon
2727 pgh repo writers <name> List writers
2828 pgh repo grant-writer <name> --peer <url> [--role owner|writer]
2929 Admin: grant a peer push authority
30 pgh repo set-head <name> <branch> Set the repo's DEFAULT BRANCH fleet-wide
31 (replicated; admin; run on the tracker
32 owner). Accepts main or
33 refs/heads/main.
3034 pgh repo local-key <name> Print this daemon's tracker local key
3135 pgh repo revoke <name> <userId> Revoke a writer
3236 pgh repo resync <name> Heal a stuck tracker: clean re-join in
……@@ -66,6 +70,17 @@ export async function run (client, args) {
6670 return client.call('repo-tags', { name })
6771 }
6872
73 // Default branch. HEAD used to be per-backend, so nodes disagreed and the
74 // public saw whichever the load balancer hit; it is replicated now, but a
75 // repo whose nodes already disagree gets seeded by whichever writer
76 // reconciles first. This makes that a deliberate choice rather than a race.
77 if (sub === 'set-head') {
78 const name = args[1]
79 const ref = args[2]
80 if (!name || !ref) throw new Error('usage: pgh repo set-head <name> <branch>')
81 return client.call('repo-set-head', { name, ref })
82 }
83
6984 // Host a new bare repo in one call: init --bare + symbolic-ref HEAD + scan +
7085 // serve, all daemon-side. Must be matched BEFORE the bare-name fallthrough at
7186 // the bottom, or `create` would be read as a repo name to show.
package.json +1 -1
……@@ -1,6 +1,6 @@
11{
22 "name": "pgh",
3 "version": "0.1.130",
3 "version": "0.1.131",
44 "description": "pgh — P2P content-addressed package manager and app launcher",
55 "type": "module",
66 "main": "index.js",