Git Branching Workflow
Compare common branching models and choose one that matches team size, release cadence, and review needs.
A model is a contract, not a Git command
Git Branch already taught the pointer: a name that moves with new commits. A branching model is the team agreement about which names exist, how long they live, and how they return to the default branch. Git will create any name you type. It will not tell you whether that name belongs in this repository.
Branch pointers
git switch, git merge, and git rebase move history. They do not choose GitHub Flow or Git Flow.
GitHub Flow
A GitHub convention: short-lived branches return through pull requests into main. There is no git github-flow.
# These are Git. None of them selects GitHub Flow, trunk-based, or Git Flow.
git switch -c feature/search
git merge feature/search
git rebase origin/mainGitHub Code Review assumed a feature branch and a reviewed merge. This lesson names that path as a model, compares two others, and makes you write the choice down so the next person does not invent a second default branch.
GitHub Flow
GitHub Flow is the shape this course has already been using: update main, branch for one intention, open a pull request, review, merge, delete the branch. main is always releasable in principle. There is no long-lived develop.
Default branch
main (or whatever GitHub shows as default). Production history lives here.
Feature branches
Short-lived. One claim per branch. Named for the work, not for a season.
Return path
A GitHub pull request, then a merge strategy you can justify. Direct pushes to main skip review.
After merge
The feature branch is finished. New work starts from an updated main, not from the old feature tip.
Two Clone Sync pushed to main because the job was two working copies sharing history. That was Git sync, not GitHub Flow. Once review exists, main moves through a pull request.
Trunk-based development
Trunk-based development also treats one branch as the source of truth—usually main, called the trunk. The difference is cadence. Changes are tiny. Branches last hours, or you commit to the trunk behind a flag. Integration is constant, so merge conflicts stay small.
What it shares with GitHub Flow
One long-lived default branch. Short-lived work. No develop line that lags main for weeks.
What it insists on
Land on the trunk often. A week-old feature branch is already a smell. GitHub Flow allows a pull request that lives a few days; trunk-based wants that window even smaller.
GitHub is optional
Trunk-based is a Git integration habit. You can do it with two clones and no pull requests. GitHub Flow is the GitHub-shaped version of short-lived branches.
This course
For a practice repository, GitHub Flow is the honest label: you already open a pull request. Do not call it trunk-based unless you actually integrate many times a day.
Git Flow names, not Git objects
Git Flow is a popular naming scheme: main for supported releases, develop for integration, feature/* off develop, release/* when you cut a version, hotfix/* off main. Every one of those is an ordinary Git branch. Git does not create them at git init. GitHub does not add them when you click Create repository.
When it earns its keep
You ship numbered releases and must patch 1.4 while 1.5 is still in progress. Then a supported main and an integration line can be real jobs.
When it is costume
A single-person practice repo with no customers and no old version to patch. Extra long-lived branches become a second main you forget to merge.
No required helper
Third-party git-flow scripts are not Git. Do not install them as a lesson requirement. If you need those names, git switch -c develop is enough—and you should still be able to say why develop exists.
Merge still means merge
Returning a feature still uses Git Merge or a GitHub merge button. Git Flow does not invent a fourth kind of history.
Choose by size, cadence, and review
Pick a model you can defend in one paragraph. Write it in the repository. Do not mix a silent develop into GitHub Flow “just in case.”
Team size
One or two people on a disposable repo: GitHub Flow. A large team that must keep an old release alive: Git Flow may be justified—name the release you are protecting.
Release cadence
Continuous deploy from main fits GitHub Flow or trunk-based. A scheduled train with hotfix lines fits Git Flow.
Review needs
If every change should be discussed, GitHub Flow plus code review is the path. Trunk-based still needs a review habit; it just refuses long-lived review branches.
This lab
Choose GitHub Flow for the practice remote. State that choice in WORKFLOW.md. Do not create develop to look professional.
Run one short-lived branch
Start from an up-to-date main. One branch, one document: the model itself. Push the branch. Open a pull request the way GitHub Pull Requests already taught. Do not commit the workflow note on main first and then try to invent a model around it.
# Branching model
This repository uses GitHub Flow.
- Default branch: main
- A change lives on a short-lived feature branch
- The branch returns through a GitHub pull request, then is deleted
- Do not commit review work on main
- Do not keep a long-lived develop branch# From a clone of a GitHub repository YOU own
git switch main
git pull origin main
git switch -c feature/workflow-note
# Add WORKFLOW.md with the model this repo actually uses, then:
git add WORKFLOW.md
git diff --cached
git commit -m "Document the branching model this repository uses"
git push -u origin feature/workflow-noteTest what you learned
Type the command that creates and switches to a branch named feature/workflow-note.
git push -u origin feature/workflow-note publishes the branch. GitHub still has the same main until the pull request merges. That is GitHub Flow in one move: the default branch did not absorb the work yet.
Retire the branch after merge
After GitHub merges, fetch and update local main. Then delete the feature name locally and on origin. A short-lived branch that survives merge is a long-lived branch you did not admit.
# After the pull request is merged on GitHub
git fetch origin
git switch main
git pull origin main
git branch --merged main
git branch -d feature/workflow-note
git push origin --delete feature/workflow-note
git log --oneline --decorate --graph -n 8git branch -d feature/workflow-note refuses if the branch is not an ancestor of the current branch—usually because you have not updated main yet. Update first, then delete. git push origin --delete feature/workflow-note removes the GitHub branch name. It does not delete the commits that already landed on main.
Test what you learned
Type the command that deletes the local branch named feature/workflow-note after it has merged.
Test what you learned
Type the command that deletes the remote branch named feature/workflow-note on origin.
git branch --merged main lists names whose tips are already in main. Use it to catch leftover feature branches. Do not delete main.
What not to invent
A second default branch with no job
If nothing is integrating on develop except delay, you copied Git Flow names without Git Flow work.
GitHub Flow plus commits on main
If review is the path, do not also push features straight to main “because I own it,” except for the tiny setup this course already did before pull requests existed.
A git-flow install as proof
A helper script is not the model. The written contract and the graph are the model.
Protection as a substitute
Branch protection can later block direct pushes. It does not choose GitHub Flow for you. Do not configure it in this lesson.
Guided practice: name the model
- 01Pick a repository you own
Confirm
git remote -vis your GitHub URL.git switch mainandgit pull origin main. - 02Write the contract
On
feature/workflow-note, addWORKFLOW.mdthat names GitHub Flow, the default branch, the pull-request return path, and why Git Flow is not in use here. - 03Open the pull request
git push -u origin feature/workflow-note, thengh pr createas you already can. Keep the diff to that file. - 04Merge, then retire the branch
Merge on GitHub. Update local
main.git branch -d feature/workflow-note.git push origin --delete feature/workflow-note. - 05Prove the names
git branch -ashould not still list the feature branch.WORKFLOW.mdshould be onmain.
Independent lab: branching workflow
- On a GitHub repository you own, choose GitHub Flow unless you can name a real supported release that needs Git Flow. Write that choice in
WORKFLOW.mdon a short-lived feature branch—not onmain. - Push the branch, open a pull request, and merge it. Do not add a
developbranch “for later.” - Update local
main. Delete the feature branch locally withgit branch -dand on origin withgit push origin --delete. - Show
git branch -awithout that feature name, andgit log --oneline --decorate -n 5withWORKFLOW.mdonmain. - Write six lines: repository URL, model name, default branch, how a change returns, why Git Flow was or was not chosen, and one sentence that distinguishes GitHub Flow from
git switch. Do not push workflow branches to a project you do not maintain.
Common workflow mistakes
Calling git switch GitHub Flow
Switching branches is Git. GitHub Flow is the review path back to main.
Copying Git Flow names
develop without a release train is a second default branch. Name a reason or do not create it.
Leaving the feature branch
After merge, leftover names collect accidental commits. Delete the local and remote feature refs.
Mixing models in silence
A pull request into main plus an undocumented develop means nobody knows the contract. Write it or simplify it.
Lesson review
You can choose a branching model as a written contract, keep GitHub Flow distinct from Git commands and from Git Flow, and retire a short-lived branch after a reviewed merge. Branch protection that enforces the default branch is GitHub Branch Protection.
- I know a branching model is a team agreement, not a Git subcommand and not a GitHub Issue.
- I can tell GitHub Flow from trunk-based cadence and from Git Flow’s extra long-lived names.
- I can
git switch -ca short-lived branch, return it through a pull request, thengit branch -dandgit push origin --delete. - I practice on a repository I own, and I do not invent
developwithout a job for it.