Skip to content

Branches and workflow

rebaserHEAD edited this page Oct 14, 2026 · 3 revisions

explanation, committed verified 2026-10-14 stable a4e75b18

How the fork's branches are laid out, and why. To do the work, see Taking a change upstream and Syncing with upstream.

The shape

Two lines side by side

Upstream merges slowly, and we want to play on everything we've built while pull requests wait. So the fork keeps two lines running side by side: a clean one for upstream, made of one branch per change, and one you can play on, stable, which collects every change that's been seen working in game.

flowchart TD
    UP["upstream game_rework"] -->|fetch| GR["game_rework"]
    GR -->|cut| CH["change branch"]
    CH -.->|pull request| UP
    CH -->|merge --no-ff| ST["stable"]
    GR -->|merge| ST
Loading

Remotes

Remote Repository
origin rebaserHEAD/NexusForever, this fork
upstream NexusForever/NexusForever

Work in progress stays on the machine it's being written on. A branch gets pushed to origin when it becomes a pull request or has to reach another machine. stable is pushed as work lands on it.

Branches

Branch What it holds Goes upstream
game_rework Upstream's development branch, unchanged It is upstream
One per change, for example archive-packet-ids A single change: the unit of a pull request Yes
local-*, for example local-loopback Local hardening and tooling Never
stable game_rework plus every change that's been checked in game Never

Why it's built this way

The rules

Nothing is committed to game_rework. It only moves when upstream does, so it's always a true copy to cut from and to compare against.

One change per branch. A branch is the unit of a pull request, and upstream takes one concern per pull request. A change that needs another one is cut from it, and its pull request says so: galactic-archive sits on archive-packet-ids.

stable only takes merges, made with --no-ff. Each change stays visible on stable as one unit, and when upstream accepts one, it arrives through the ordinary game_rework merge on top of the copy we already have. stable is never rebased, reset or force-pushed, because everything we play on is built from it.

local-* branches never go upstream. They hold changes that only make sense here, like binding the game listeners to loopback. They reach origin through stable and are never pushed on their own.

Two working trees

The play server runs from a second worktree that holds stable, apart from the development tree.

The running servers lock their own binaries, so a build in the tree the stack runs from fails until the stack stops. With stable in its own worktree, a feature branch can be built while the server is up. Only one stack runs at a time, though: the ports are fixed and there's one database volume.

Related pages

Page Covers
Taking a change upstream A change from a fresh branch to an open pull request, by way of stable
Syncing with upstream Bringing upstream's work into game_rework and stable
Verifying a feature What "seen working in game" means before a change reaches stable

Clone this wiki locally