A branch is a movable pointer to a commit. That one fact makes cheap, isolated work possible — and makes a team's workflow either calm or chaotic.
Learning objectives
- Create, switch and delete branches.
- Follow a feature-branch workflow.
- Merge with and without fast-forward.
- Keep
maindeployable at all times.
1. The mental model
A --- B --- C main
\
D --- E feature/signup-form
main points at C. The feature branch points at E. Commits are immutable; branches are just labels that move. Creating one is instantaneous and costs almost nothing.
2. Everyday commands
git branch # list local branches
git switch -c feature/signup # create and switch
git switch main # go back
git branch -d feature/signup # delete a merged branch
git branch -D feature/signup # force delete (unmerged work is lost)
git switch is the modern command; git checkout still works and also handles files. Prefer switch for branches to avoid accidentally restoring files.
3. The feature-branch workflow
- Start from an up-to-date
main:
git switch main
git pull --ff-only
git switch -c feature/course-filters
- Commit in small, meaningful steps:
git add src/components/CourseFilters.tsx
git commit -m "Add level filter to course catalogue"
- Push and open a pull request:
git push -u origin feature/course-filters
- After review and merge, delete the branch locally and remotely.
Rules that prevent most pain:
- One branch, one purpose. A branch that fixes a typo and refactors the API is unreviewable.
- Pull
maininto your branch (or rebase) before merging, not after. - Never commit directly to
mainon a shared repository.
4. Merging
git switch main
git merge feature/course-filters
If main has not moved since the branch started, Git fast-forwards: it just moves the label. If both have new commits, Git creates a merge commit with two parents.
Force a merge commit even when a fast-forward is possible — useful for keeping feature boundaries visible:
git merge --no-ff feature/course-filters
5. Remote branches
git fetch --prune # update remote refs, remove deleted ones
git branch -vv # local branches and their upstreams
git push -u origin HEAD # push current branch and track it
origin/main is a local cache of the remote. git fetch updates it; it does not change your working tree.
6. Naming
feature/course-filters
fix/duplicate-phone-number
chore/upgrade-next
docs/lecture-stage-3
Lowercase, hyphens, a type prefix. The name should tell a reviewer what to expect before they open the diff.
7. Protecting main
On GitHub, enable branch protection: require a pull request, require CI to pass, disallow force pushes. A deployable main is a convention until it is enforced by the platform.
Common mistakes
- Working on
main"just this once". - Long-lived branches that drift for weeks — merge small changes daily.
- Deleting a branch before its PR is merged.
- Force-pushing a shared branch and rewriting someone else's commits.
Practice
Run the branching exercise in the assignment in a scratch repository. Doing it once by hand is worth more than reading it twice.