fix(release): fold the -s ours history-alignment merge into release-cut#1089
Merged
Conversation
main and develop have unrelated roots (Phase 4 filter-merge) and diverge permanently: main carries one squash commit per release that develop never sees, and the 2026-04-27 amendment removed A4 step 6 (rebase develop onto main). A vX.Y.Z branch cut cleanly from develop is therefore not mergeable into main -- GitHub cannot compute a merge ref, so the release PR sits at CONFLICTING and *no CI runs at all*: neither validate-base nor release-required-result ever trigger. Every cut before v0.3.1 (#711, #712, #1029, #1043, #1072) worked around this by hand. release-cut now performs the merge itself, between the "Release vX.Y.Z" commit and the push. -s ours records origin/main as a second parent while preserving the curated release tree byte-for-byte; release-finalize's squash-merge then collapses the branch to a single commit, so the merge never reaches main's release-only ledger. Verified: after the merge, merge-base(origin/main, HEAD) == origin/main, so GitHub's three-dot PR diff is exactly the release delta. The recipe guards the merge by asserting the tree hash is unchanged across it. A -s ours merge cannot change the tree by construction, so the guard is really an assertion that the strategy is still ours -- any other strategy drags main-only content back into the curated tree, silently un-curating the release. The guard is also a no-op-safe check: if origin/main is already an ancestor, git reports "Already up to date", the tree is unchanged, and the cut proceeds. --no-verify: git merge fires pre-merge-commit (not pre-commit). That hook is not in default_install_hook_types today, so this is defensive -- but curation has already deleted .pre-commit-config.yaml and the repo:local hook entrypoints by this point, so installing it later would otherwise break every cut here. Ordering is load-bearing: the merge must follow generate_changelog_entry.py --since-ref origin/main, which needs main to still be a non-ancestor, and must precede the push, or the PR is born CONFLICTING again. The new regression test pins all three positions plus the strategy flags. Coordination with #1027 (rename main -> release): this change uses the literal origin/main spelling that the rest of the Makefile already uses, so that PR's textual rename sweep picks these lines up with the existing ones. Expect a mechanical conflict in the release-cut header comment (step renumbering). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
joeharris76
added a commit
that referenced
this pull request
Jul 10, 2026
…ut (#1092) PR #1089 folded the `git merge -s ours --allow-unrelated-histories origin/main` history-alignment step into the `release-cut` Makefile target. Three passages across two TODO items still told the reader it was a manual step. The most consequential was in the Phase 8 item under planning/, which is forward-looking guidance: it instructed a future release cutter to perform the merge by hand. That is now wrong and would have produced a redundant second merge. The two passages in release-recovery-v0-3-1 are historical records of the v0.3.1 cut, so they keep the past tense ("release-cut did not do this at the time") and gain a pointer to #1089 rather than being rewritten as if the target always had the merge. Incidentally makes the pre-existing "(both fixed, see w7)" line in release-recovery-v0-3-1 true: at the time it was written only one of the two gaps was actually fixed. Co-authored-by: Joe Harris <57046+joeharris76@users.noreply.github.com> Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
main and develop have unrelated roots (Phase 4 filter-merge) and diverge
permanently: main carries one squash commit per release that develop never
sees, and the 2026-04-27 amendment removed A4 step 6 (rebase develop onto
main). A vX.Y.Z branch cut cleanly from develop is therefore not mergeable
into main -- GitHub cannot compute a merge ref, so the release PR sits at
CONFLICTING and no CI runs at all: neither validate-base nor
release-required-result ever trigger.
Every cut before v0.3.1 (#711, #712, #1029, #1043, #1072) worked around this
by hand. release-cut now performs the merge itself, between the
"Release vX.Y.Z" commit and the push.
-s ours records origin/main as a second parent while preserving the curated
release tree byte-for-byte; release-finalize's squash-merge then collapses
the branch to a single commit, so the merge never reaches main's
release-only ledger. Verified: after the merge, merge-base(origin/main, HEAD)
== origin/main, so GitHub's three-dot PR diff is exactly the release delta.
The recipe guards the merge by asserting the tree hash is unchanged across
it. A -s ours merge cannot change the tree by construction, so the guard is
really an assertion that the strategy is still ours -- any other strategy
drags main-only content back into the curated tree, silently un-curating the
release. The guard is also a no-op-safe check: if origin/main is already an
ancestor, git reports "Already up to date", the tree is unchanged, and the
cut proceeds.
--no-verify: git merge fires pre-merge-commit (not pre-commit). That hook is
not in default_install_hook_types today, so this is defensive -- but curation
has already deleted .pre-commit-config.yaml and the repo:local hook
entrypoints by this point, so installing it later would otherwise break every
cut here.
Ordering is load-bearing: the merge must follow generate_changelog_entry.py
--since-ref origin/main, which needs main to still be a non-ancestor, and
must precede the push, or the PR is born CONFLICTING again. The new
regression test pins all three positions plus the strategy flags.
Coordination with #1027 (rename main -> release): this change uses the literal
origin/main spelling that the rest of the Makefile already uses, so that PR's
textual rename sweep picks these lines up with the existing ones. Expect a
mechanical conflict in the release-cut header comment (step renumbering).
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com