A branch is just a movable label pointing at a commit — that is the whole implementation, and internalising it dissolves most branch anxiety. Creating one costs nothing, switching is instant, and deleting a merged one loses nothing.

Creating and switching #

The modern single command
$ git switch -c feature/toc        # create and switch
$ git switch main                  # back to main
$ git branch feature/toc main      # create without switching (classic)
$ git checkout -b feature/toc      # the older equivalent

git switch arrived in git 2.23 to split the two jobs checkout had been doing — moving branches versus moving files. switch does branches only; restore does files only. Both are clearer than checkout's double life.

Seeing the branches #

Local, remote, and the last commit on each
$ git branch -vv
* main               f3e2d1c [origin/main] fix: cache headers
  feature/toc        9a8b7c wip: toc markup
$ git branch -a                   # includes remotes/origin/*
$ git branch --merged main        # safe-to-delete list

-vv shows tracking relationships — which local branch follows which remote one — which is what you need before a push or a pull.

Where branches start #

A new branch grows from the current commit unless you say otherwise — and choosing the right starting point is half of branching well:

Start fromCommandWhen
Current HEADgit switch -c fix/xThe usual case
Fresh maingit switch -c fix/x origin/mainStarting from current production
A specific commitgit switch -c fix/x f3e2d1cBisect follow-ups, archaeology
A taggit switch -c hotfix v1.4.0Production hotfixes

Deleting and renaming #

Removal, with the safety valve
$ git branch -d feature/toc        # refuses if unmerged
$ git branch -D feature/toc        # force — loses the label only
$ git branch -m feature/toc feature/table-of-contents

Deleting a branch deletes the label; the commits stay in the repository until garbage collection, which is why even -D accidents are recoverable through reflog. -d refusing to delete unmerged work is the safety valve — respect it unless you mean it.

The naming scheme that scales #

A convention that answers questions later
feature/toc          new capability
fix/cache-headers    bug repair
hotfix/v1.4.1        urgent production fix, cut from a tag
release/v1.5         stabilization before a release

Slashes create namespaces in every git tooling; prefixes sort naturally and say what the branch is before anyone reads its commits.

Uncommitted work that blocks a switch belongs to stash; parallel checkouts without switching are worktrees. The Git series continues.