Branches are pointers

Treat a branch as what it is — a moving name for one commit — and move between them without fear.

07of 16
≈ 12Min read
5Parts

Forty bytes

That is the whole branch. Creating one writes a file; deleting one removes a file; the commits are untouched either way. This is why git branches are instant and why people make them for a twenty-minute experiment.

HEAD is a second pointer that usually says which branch you are on (ref: refs/heads/main). Committing moves the branch that HEAD names — which is how a branch "advances" while you work.

a branch, on disk
$ cat .git/refs/heads/main
832dbe33b4928b0212c852ef7bee09f285622556

The commands

switch is the modern spelling; checkout still works
git branch                     # list
git branch fitting-notes       # create, and stay where you are
git switch fitting-notes       # move
git switch -c fitting-notes    # create and move  (git checkout -b)
git switch -                   # back to where you were
git branch -d fitting-notes    # delete — refuses if it is not merged
git branch -D fitting-notes    # delete anyway
git branch -m old new          # rename
Why switch and restore exist

checkout did two unrelated jobs: move between commits, and overwrite files. Git 2.23 split them into switch and restore. Old documentation, and every colleague, still says checkout.

What switching changes

Switching rewrites the working tree and the index to match the branch you are moving to, and leaves your uncommitted changes alone if it can. If they would be overwritten, git refuses and says so. Commit or stash first; git is protecting work you have not saved.

Detached HEAD

It is not an error state — it is what "I am looking at this exact commit" means, and it is how CI checks out a revision. Just remember that commits made there need a branch before you walk away, or only the reflog knows about them.

looking at a commit instead of a branch
git switch --detach HEAD~3      # or: git checkout 832dbe3

# HEAD now points at a commit, not a branch.
# commits made here belong to nothing, and become unreachable when you leave.

git switch -c rescue            # …unless you give them a name

Branches are for separating changes, not people

One branch per piece of work, named after the work — fix-discount-total, not ulvi-2. Short-lived: a branch that is open for three weeks is three weeks of divergence and a conflict at the end. Delete it after it merges; the commits live on in the history, and the name has done its job.

Practice