branching: the merge methods the orchestrator is told to use #171

Merged
emi merged 1 commit from docs/branching-merge-methods into dev 2026-08-02 01:06:43 +00:00

View file

@ -134,7 +134,7 @@ You merge **one PR into `dev` at a time**. For each:
3. `forge_pr_await(pr=N, until="checks_complete")` — checks on the **rebased** 3. `forge_pr_await(pr=N, until="checks_complete")` — checks on the **rebased**
head. The run you saw before the update was for a merge base that no longer head. The run you saw before the update was for a merge base that no longer
exists. exists.
4. `forge_pr_merge(pr=N, method="rebase", delete_branch=true)`. 4. `forge_pr_merge(pr=N, method="squash", delete_branch=true)`.
5. Only then move to the next PR. 5. Only then move to the next PR.
`block_on_outdated_branch` is set on `dev`, so Forgejo enforces step 2 rather `block_on_outdated_branch` is set on `dev`, so Forgejo enforces step 2 rather
@ -150,7 +150,7 @@ context. Do not resolve a large conflict on someone else's behalf.
Promote when `dev` is green and a coherent batch is complete — not on a timer, Promote when `dev` is green and a coherent batch is complete — not on a timer,
not mid-feature. `promote(from="dev", to="main")` opens the PR with the not mid-feature. `promote(from="dev", to="main")` opens the PR with the
divergence, the conflict prediction and the changelog written into its body. divergence, the conflict prediction and the changelog written into its body.
Merge it with `method="merge"`. Merge it with `method="fast-forward-only"`.
Unready work belongs behind a feature flag, or not on `dev` yet. **Never promote Unready work belongs behind a feature flag, or not on `dev` yet. **Never promote
around it with cherry-picks.** around it with cherry-picks.**
@ -161,17 +161,23 @@ SHAs, and merging it would fire the target's deploys for nothing.
### Promotion: `main``release` ### Promotion: `main``release`
Prepare with `promote`, then ask. On the owner's yes, merge with `method="merge"` Prepare with `promote`, then ask. On the owner's yes, merge with
and tag it: `forge_releases(create={tag:"v<semver>", target:"release", ...})`. `method="fast-forward-only"` and tag it: `forge_releases(create={tag:"v<semver>", target:"release", ...})`.
**On fast-forward.** The written policy is that `release` moves only by **On fast-forward.** Both promotions move by fast-forward, and as of
fast-forward. It cannot today: every promotion so far has been a merge commit 2026-08-01 that is in force rather than aspirational. It was blocked until then
*into* the target, which the source never receives, so the branches are mutually for a structural reason worth remembering: every promotion had been a merge
divergent by construction and Forgejo will refuse a `fast-forward-only` merge — commit *into* the target, which the source never receives, so the branches were
correctly. The style is implemented and accepted by `forge_pr_merge`; adopting mutually divergent by construction and Forgejo refused `fast-forward-only`
it needs a one-time reconciliation of the protected branches, which is the correctly. The one-time reconciliation the old policy was waiting for has
owner's decision. Until that happens, promotions are merge commits. Do not happened; the trees were already identical, so it carried no content.
attempt to "fix" this with a rebase or a force-push.
`release ⊆ main ⊆ dev` now holds, and a promotion lands the branches on the
same SHA rather than merely the same tree. Merge commits and rebase merges are
disabled repo-wide, so a slip fails loudly instead of quietly re-diverging the
chain. If Forgejo refuses with "diverging branches", the target has picked up a
commit the source lacks — reconcile it once, target into source, fast-forward.
Do not attempt to "fix" it with a rebase or a force-push.
### Hotfix ### Hotfix