Up to now, all your commits have piled up in a single line on the
main branch. That's fine for solo work. But once you're
experimenting with an idea, or working with someone else, you'll
want to make commits that don't affect the main line of history
until you're ready. That's what branches are for.
A branch is just a pointer to a commit
This is the mental model that unlocks everything else about Git. When you hear "branch" your brain probably pictures a whole copy of the project, tucked away somewhere. That's not what Git does.
A branch is a label attached to one specific commit. That's the entire thing. The commits themselves are the tree of your project's history; branches are just sticky notes with names on them, stuck to particular commits.
So main isn't a folder or a file. It's a name pointing at a
commit. When you make a new commit while main is your current
branch, main slides forward to point at the new commit. That's
what "advancing a branch" means.
Creating a branch without switching
The command to create a new branch is:
git branch feature
This makes a new label called feature and points it at the
commit you're currently sitting on. It does NOT move you onto that
branch. You're still on main, still working the same way as
before, but now there's a second label sitting on the same commit.
Run git branch (no arguments) to see the list:
* main
feature
The * shows which branch you're on. Both point at the same
commit right now, but they're independent pointers. As soon as you
switch to feature and start committing, they'll diverge.
Why "just create" and "create and switch" are separate
Git also has commands that create a branch AND switch to it in one
step (git switch -c, git checkout -b). Both are useful. But
the two operations are conceptually distinct:
- Creating puts a label on a commit.
- Switching moves your working directory to match that label.
Keeping them separate in your head makes the mechanical parts of branching feel less magical. Everything Git does with branches is some combination of these two operations.
Naming branches
Convention: branches are named after what they're for. Some common patterns:
feature/login-formfix/wrong-copy-in-headerrefactor/split-user-service
Slashes are allowed and useful for grouping. Spaces are not allowed. Names are case sensitive. Keep them short.