Branches are a pointer, and that is all
A branch is a movable label on a commit, which is why branching costs nothing.
A label, not a copy
A branch is a file containing a commit id. Creating one writes forty-odd bytes; it does not copy your code. This is why Git encourages branches where older systems made them an event.
HEAD is a pointer to the branch you are on. Committing moves the branch forward to the new commit, and HEAD follows because it points at the branch rather than the commit. "Detached HEAD" means HEAD points straight at a commit with no branch — you can look around and even commit, but nothing is holding those commits, and that is the part that surprises people.
Remote branches are a memory, not a live view
`origin/main` is your last known position of main on the remote, recorded at your last fetch. It does not update by itself, so "origin/main is two commits behind" may simply mean you have not fetched today.
`git fetch` updates those memories and changes nothing else — it is always safe. `git pull` is fetch plus merge, which does change your working branch. Knowing they are different is what lets you look before you leap: fetch, read the log, then decide.
Worked examples
Look at what arrived before merging any of it
/git fetch && git log --oneline HEAD..origin/main/Against:
On a branch tracking origin/mainHEAD..origin/main reads "commits on origin/main that I do not have". Reverse it to see what you have that they do not.
Check yourself
Practice questions written for this lesson — not past exam papers.
Practise every question in this subject
What is a branch?
What does git fetch change?