sirius-press/docs/upstream-merges.md
Silent Mode a65556726e docs(sirius-press): say that the forge repo is a mirror, and what that costs
Someone who clones from code.silentmode.st and starts working will otherwise
find out the hard way: push-split.sh force-pushes master, so their branch
does not survive the next mirror push. Better to say it on the page that
tells people how to take an upstream release, since that is exactly the work
that would be lost.
2026-09-21 03:23:14 +02:00

5.4 KiB

Keeping up with WordPress

WordPress ships security releases, and a fork that cannot take them quickly is a liability rather than a project. This page is how Sirius Press takes them.


The arrangement

WordPress lives in this repository, at wordpress/, as a git subtree. The fork's own change sits on top of it as an ordinary commit.

Three pieces make that work:

wordpress/ The vendored tree, patched. This is what gets built and shipped.
sirius-press/wordpress-upstream A branch holding pristine upstream releases, one commit each, never edited. The other side of the merge.
patches/ A readable record of what the fork changes in core. Generated, not maintained.

The entire core diff is one file, 75 lines: wp-admin/install.php, the setup wizard. Everything else Sirius Press does is plugins and hooks.

Why a subtree and not a patch series

Because a three-way merge understands something a patch does not. When upstream edits lines near the fork's change, git subtree merge merges them and moves on; patch either applies with fuzz and hopes, or fails and hands you the job of re-deriving the change by hand. A conflict from the merge is resolved once, in the file, and stays resolved — the next release merges against the resolution.

The cost is repository size: WordPress is about 149 MB and 3,800 files. That is the price of a fork that can take a security release in a minute, and it is the right trade for a project whose whole argument is that it should outlive its maintainers' attention.


Taking a new release

tools/update-wordpress.sh 7.1.2

It downloads the release, checks it against the SHA-1 wordpress.org publishes, imports the pristine tree onto sirius-press/wordpress-upstream, and merges that branch into wordpress/. Then it updates tools/wordpress.lock and regenerates patches/.

Two outcomes.

Clean. The merge went through. Run the tests, build, commit. Usually a minute of work.

Conflicted. Upstream changed the same lines the fork changes — in practice, wp-admin/install.php. Git leaves the conflict in the file:

git status
$EDITOR wordpress/wp-admin/install.php
git add wordpress/wp-admin/install.php
git commit
tools/refresh-patches.sh

Then set WP_VERSION, WP_URL, WP_SHA256 and WP_SHA1 in tools/wordpress.lock by hand, since the script stopped before it got there.

Either way the fork is not broken while you work: the merge is in your working tree, and until you commit it, wordpress/ still holds the last version that worked.


After any bump

tests/run.sh
tools/build.sh

The suite does not test core, but it tests every assumption the fork makes about it. Then walk through wp-admin/install.php once in a browser — the setup wizard is the only patched file, so it is the only thing an upstream change can break in a way the tests would miss. testing.md has a recipe for a throwaway instance that needs no database server.


Keeping patches/ honest

patches/ is documentation. It answers the question anyone auditing this fork asks first — what exactly did you change inside WordPress? — in a minute, which git log wordpress/ cannot, because that log is mostly upstream imports.

It is generated from the tree, never edited:

tools/refresh-patches.sh          # rewrite it
tools/refresh-patches.sh --check  # fail if it has drifted (for CI)

Generated documentation stays true. A hand-maintained record of a fork's core diff drifts, and a stale one is worse than none, because people trust it.


Changing core yourself

Edit the file under wordpress/ and commit it like any other change. The next upstream merge will three-way it.

Before you do: check whether a plugin hook can carry the change instead. Every line added to wordpress/ is a line that can conflict with upstream forever, and the reason this fork's merges are cheap is that there are only 75 of them. The registration form, the password-reset page and the mail pipeline were all replaced from plugins precisely so they would never appear in this directory.


Where this repository lives

code.silentmode.st/silentmode/sirius-press is a mirror. Sirius Press is developed inside the Silent Mode monorepo and split out with scripts/push-split.sh, which force-pushes master each time. History on the forge is real — file blame points at the actual commits — but it is rewritten on every push, so a pull request against it will not survive.

What that means in practice:

  • Silent Mode takes upstream releases in the monorepo, where the subtree's merge history is intact, and the result is mirrored here.
  • A downstream fork that clones from the forge and wants to bump WordPress itself should treat its clone as the source of truth from that point on and stop pulling the mirror, because the next mirror push will not merge with its work.

Patches and bug reports are welcome as issues; code is easiest to take as a diff rather than as a branch.


If the upstream branch is missing

A clone made with --single-branch will not have sirius-press/wordpress-upstream, and tools/update-wordpress.sh will say so rather than guessing. Fetch it:

git fetch origin sirius-press/wordpress-upstream:sirius-press/wordpress-upstream

Building and running do not need it — only taking a new upstream release does.