The Coach2Lead Git Flow
your tool:
you are:

How we ship code
without breaking main

Topic branches, squash merges, one cherry-picked commit at a time. Our whole git flow, drawn out below. Click through it, then keep this page open on your second monitor while you work.

Walk the flow 10 steps, ~2 minutes
Coach2Lead team zine · issue #1
it's commits all the way down.

this is Ref, our branch wizard.
the hat is non-negotiable.

Walk the flow

One finished task travels: topic branch → your personal branch → promote branch → main. Step through it and watch the graph draw itself.

based on a true story: this exact run shipped the page you are reading — issue #6PR #3PR #5main. one wrong merge button along the way, zero casualties. (every link is the real thing.)

main protected: nothing lands here without CI + review lars your personal branch: forked from main, one each arno robbin merge main into lars topic/git-workflow-guide new branch commit wip commit oops, fix commit works! PR #1: squash & merge "add the git workflow guide (#3)" 1t 8e529a9 copy this! promote/git-workflow-guide new branch fresh from main! the copy original stays put CI RV two locks: CI + Robbin shipped! in sync dead branches deleted; ready for the next task
  • main
  • lars
  • topic/…
  • promote/…

    Personal branches never merge into main

    Your personal branch collects everything: finished work, half-finished experiments, old syncs. Merging it into main would drag all of that along. The only thing that ever travels to main is a promote/… branch carrying one cherry-picked squashed commit. That's the whole trick.

    Why this dance?

    Three moves that look like ceremony until you see what each one buys you.

    wip oops works! one clean commit

    Why squash?

    Your topic branch is allowed to be messy — that's what it's for. The squash merge folds all of it into one tidy commit on your personal branch, with the PR title as its message. History stays readable, and promotion becomes possible: you can only cherry-pick "the work" if the work is one commit.

    unfinished old sync just this one

    Why cherry-pick?

    The promote branch starts from fresh main and receives exactly one commit — by SHA, so there is no guessing. It cannot drag along your personal branch, no matter how far it has drifted. Finished work travels; everything else stays home.

    CI RV green build + Robbin's approval

    Why the locks?

    Branch protection on main means the merge button stays grey until CI passes and Robbin approves. So experiment freely: the repo's rules, not your nerves, are what keep main safe. You genuinely cannot break it from a branch.

    From feedback to branch

    Customer feedback lands as a GitHub issue, and the issue number becomes the name of the work everywhere else. Here's the loop — starring a made-up issue #47 — and the exact moments where things get linked.

    One piece of feedback, start to finish

    1. Find or open the issue. One issue per feedback item; give it its type and difficulty labels. All discussion, screenshots, and decisions live there.
    2. Assign yourself. That's the "I'm on it" signal, so no two people grab the same feedback.
    3. Branch off your personal branch with the issue number first: topic/47-export-crash. GitHub doesn't parse branch names; the number is for humans, and it's enough.
    4. Work and push as usual (steps 3–4 of the flow above). A pushed commit that mentions #47 adds a little cross-reference to the issue's timeline — nice, optional.
    5. Open PR #1 with Fixes #47 in the description — this is the linking moment. The PR and the issue now point at each other under Development on both pages.
    6. Squash and merge, keeping Fixes #47 in the squash message. The keyword rides the cherry-pick all the way to the promote PR…
    7. …and the moment that lands on main, the issue closes itself. Open while the fix only exists in your personal branch, closed exactly when customers actually have it.

    forgot the magic words? link the PR from either Development sidebar afterwards, or close the issue by hand with a comment. nothing is ever lost. true story: this page was issue #6 — it closed itself the second PR #5 hit main.

    One counter, two kinds

    Issues and pull requests share a single number sequence per repository — a PR is secretly a special kind of issue. That's how feedback can be issue #2 while the next PR becomes #3. A bare #47 in any text links to whatever owns that number, so it can never point at the wrong thing.

    Link vs close

    #47 on its own only links. Fixes #47, Closes #47, or Resolves #47 auto-closes the issue — but only when the commit reaches main. On your personal branch nothing fires, and that's correct: the feedback isn't done until it ships.

    the web shortcut, carefully

    The issue page's Create a branch button links branch and issue instantly, but it branches off main by default. If you use it, click Change branch source and pick your personal branch, then fetch in GitHub Desktop. Branching locally with the number in the name is the simpler habit.

    The cheat sheet

    The whole loop as commands, for when you know what to do and just need the how. Desktop / VS Code folks: the stepper above is your cheat sheet.

    One task, start to finish

    # start clean (once per task) $ git fetch origin $ git switch lars $ git merge origin/main # branch + work (repeat commits as needed) $ git switch -c topic/<task> $ git add -A $ git commit -m "what you did" $ git push -u origin topic/<task> # on GitHub: PR topic -> lars, "Squash and merge" # bring the squashed commit home + grab its SHA $ git switch lars $ git pull $ git log --oneline -1 # promotion ramp: fresh main + one cherry-pick $ git fetch origin $ git switch -c promote/<task> origin/main $ git cherry-pick <sha> $ git push -u origin promote/<task> # on GitHub: PR promote -> main # (CI green + review, then merge) # tidy up $ git switch lars $ git branch -D topic/<task> $ git branch -D promote/<task> $ git fetch --prune

    pink bits = fill in your own; yellow = your personal branch (change your name up top)

    Naming things

    branchpatternexample
    mainjust mainmain
    personal branchyour first namelars
    topictopic/task-in-kebab-casetopic/git-workflow-guide
    promotepromote/ + same task namepromote/git-workflow-guide

    short, lowercase, dashes-not-spaces. "topic/stuff" tells nobody anything. working from an issue? number first: topic/47-export-crash.

    Lost? Find your feet

    # where am I, what changed? $ git status $ git branch --show-current $ git log --oneline -5

    still lost? ping Robbin. really — that's the mentor deal.

    House rules

    • Never merge your personal branch into main. Promote one squashed commit instead.
    • Personal branches receive only two things: squash merges from topics, syncs from main.
    • One topic = one task. Days, not weeks: small PRs get reviewed fast.
    • One issue = one topic branch. The number rides the branch name, the PR links it, main closes it.
    • Push topic branches often. It's your backup, and Robbin can peek early.
    • Delete merged branches: a clean branch list is a kindness to everyone.
    • Never force-push a branch someone else may have pulled.