Git branching

Bits (user-supplied, 2026-10-09) for the two-branch model — develop as integration, master as released — plus mermaid diagrams and the exact commands.

The model

Two long-lived branches: develop (integration, everything lands here first) and master (released/promotable state). No direct commits to either — everything travels by PR.

flowchart LR
    subgraph feature development
        direction LR
        F["feature/my-feature"] -->|"PR -> develop<br/>(CI + review)"| D
    end
    D["develop"] -->|"PR (promotion)"| M["master"]
    D -.->|"fix PR (bug found)"| D

Feature lands on develop

  1. Contributor creates feature/my-feature from develop.
  2. Opens a PR targeting develop.
  3. CI and review pass; the PR is merged.
  4. If a bug is found, open a separate fix PR targeting develop.
# contributor
git switch develop && git pull
git switch -c feature/my-feature
# ...work...
git push -u origin feature/my-feature
# open PR: feature/my-feature -> develop (Gitea/GitHub)

Maintainer workflow: release only B

Situation: develop holds features A and B; A is still broken and B is independent. Two options.

If B can wait, fix A on develop first. This is the simplest workflow: the PR from develop to master contains both features and the fix.

flowchart LR
    A["feature A (broken)"] --> D["develop"]
    B["feature B"] --> D
    D -->|"fix PR heals A"| D2["develop (A fixed)"]
    D2 -->|"PR: both + fix"| M["master"]
git switch develop
git switch -c fix/feature-a   # separate fix PR targeting develop
# ...fix...
git push -u origin fix/feature-a
# merge fix PR -> develop, then open PR: develop -> master

Option 2 — Promote B directly using a PR

If B must ship before A is fixed: create a branch from master and cherry-pick B’s changes onto it. Open a PR in Gitea/GitHub (target: master). After merging, continue development on develop as usual. This works best when B is independent of A. If B was merged with a squash commit, cherry-pick that squash commit.

flowchart LR
    A["feature A (broken)"] --> D["develop"]
    B["feature B"] --> D
    M0["master"] -->|"branch release/b-only"| R["release/b-only<br/>(cherry-pick B)"]
    R -->|"PR -> master"| M1["master (B only)"]
git switch master && git pull
git switch -c release/b-only
git log --oneline develop            # find B's commit(s)
git cherry-pick <B-commit>           # squash merge? cherry-pick the squash commit
# resolve conflicts if B touched A's code -> reconsider (not independent)
git push -u origin release/b-only
# open PR: release/b-only -> master

Where it fits

  • The squash-cherry-pick note is the practical hinge of Option 2 — same family as Git commit messages (squash merges make history clean but unreferenceable).
  • Promotion discipline (develop → master PRs) pairs with Git hooks (pre-push as the last automated gate) and Golden repo’s CI baseline.