| … | … | @@ -27,6 +27,14 @@ export const usage = `pgh repo — browse repos served by the daemon |
| 27 | 27 | pgh repo writers <name> List writers |
| 28 | 28 | pgh repo grant-writer <name> --peer <url> [--role owner|writer] |
| 29 | 29 | Admin: grant a peer push authority |
| 30 | pgh repo retire <name> Tombstone a repo: stop listing/serving/ |
| 31 | re-creating it fleet-wide. Bytes are |
| 32 | NOT removed — remove ~/git-repos/ |
| 33 | <name>.git by hand on each peer AFTER |
| 34 | the tombstone has replicated. Admin, |
| 35 | primary only. |
| 36 | pgh repo unretire <name> Undo a retire (a later op wins). |
| 37 | pgh repo list-retired Show the replicated tombstone set. |
| 30 | 38 | pgh repo set-head <name> <branch> Set the repo's DEFAULT BRANCH fleet-wide |
| 31 | 39 | (replicated; admin; run on the tracker |
| 32 | 40 | owner). Accepts main or |
| … | … | @@ -82,6 +90,28 @@ export async function run (client, args) { |
| 82 | 90 | // public saw whichever the load balancer hit; it is replicated now, but a |
| 83 | 91 | // repo whose nodes already disagree gets seeded by whichever writer |
| 84 | 92 | // reconciles first. This makes that a deliberate choice rather than a race. |
| 93 | // Retirement. Deleting a bare repo by hand does NOT stick: four paths |
| 94 | // resurrect it (cross-peer re-pull, boot rescan, directory watcher, residual |
| 95 | // references in issue-registry-index.json / tracker autobases). The tombstone |
| 96 | // must replicate to every peer BEFORE anyone removes bytes. See |
| 97 | // pear-git-v3/lib/services/retired-repos.js, which never deletes anything and |
| 98 | // is explicit that removing bytes is a manual per-peer operator action. |
| 99 | if (sub === 'retire') { |
| 100 | const name = args[1] |
| 101 | if (!name) throw new Error('usage: pgh repo retire <name>') |
| 102 | return client.call('retire-repo', { name }) |
| 103 | } |
| 104 | |
| 105 | if (sub === 'unretire') { |
| 106 | const name = args[1] |
| 107 | if (!name) throw new Error('usage: pgh repo unretire <name>') |
| 108 | return client.call('unretire-repo', { name }) |
| 109 | } |
| 110 | |
| 111 | if (sub === 'list-retired' || sub === 'retired') { |
| 112 | return client.call('list-retired-repos', {}) |
| 113 | } |
| 114 | |
| 85 | 115 | if (sub === 'set-head') { |
| 86 | 116 | const name = args[1] |
| 87 | 117 | const ref = args[2] |