Git Course 0%

What a branch really is

Intermediate Core Git Git CLI ≈ 10 min

What you will learn

  • Why a branch is a pointer, not a copy of the files
  • What happens to the pointer when you commit, and what happens to your files when you switch
  • How to read branches in git branch, git log --graph and the .git folder

After this lesson you can

  • I can look at a branch graph and say which commits belong to which branch
  • I know why creating a branch costs nothing and why deleting one rarely loses anything

Why this matters

People imagine a branch as a copy of the project, and then everything about branches feels heavy: copying takes time, switching means moving folders, deleting throws work away. None of that is true. A branch is a 41-byte file containing a hash. Once you see it that way, every branch operation becomes cheap and predictable.

A label on a commit

A branch is a pointer Left panel, before: three commits C1 to C3; both main and the new branch docs/12 point at C3, and HEAD points at docs/12. Right panel, after one commit on the branch: a new commit C4 whose parent is C3; docs/12 and HEAD moved to C4; main still points at C3. BEFORE: git switch -c docs/12 AFTER: one commit on docs/12 C1 C2 C3 main docs/12 HEAD two labels, one commit; no files changed C1 C2 C3 C4 main docs/12 HEAD the branch label moved; main did not
Creating a branch adds a label at the current commit; committing on the branch moves only that label.

The commits themselves belong to no branch. A commit is "on" a branch if you can reach it by starting at the branch's pointer and following parents backwards. That is why one commit can be on several branches at once, and why merging is about moving pointers.

Watch it in the playground's history. Right after creating a branch, both labels sit on the same commit:

Terminal
$ git switch -c docs/12-windows-install-steps
Switched to a new branch 'docs/12-windows-install-steps'
Terminal
$ git log --oneline --graph --all --decorate
* 8fa922e (HEAD -> docs/12-windows-install-steps, tag: v1.2.0, origin/main, main) Initial import of trailguide

After one commit on the branch, only its label moved:

Terminal
$ git log --oneline --graph --all --decorate
* 510f1e0 (HEAD -> docs/12-windows-install-steps) docs: add Windows steps to installation guide (#12)
* 8fa922e (tag: v1.2.0, origin/main, main) Initial import of trailguide

main still points at 8fa922e. HEAD -> docs/12-… says which branch you are on, and therefore which label will move with your next commit.

Listing branches

Terminal
$ git branch
* docs/12-windows-install-steps
  main

The * marks the current branch. git branch -a adds the remote-tracking branches (remotes/origin/main); git branch -vv shows each branch's commit and which remote branch it tracks:

Terminal
$ git branch -vv
* docs/12-windows-install-steps 510f1e0 [origin/docs/12-windows-install-steps] docs: add Windows steps to installation guide (#12)
  main                          8fa922e [origin/main] Initial import of trailguide

Switching changes your files

Switching branches makes the working tree match the branch's commit: files that differ are rewritten, files that exist only on the other branch appear or disappear. That is not deletion; it is Git showing you a different snapshot. Your uncommitted edits, however, come along only if they do not conflict with the switch — otherwise Git refuses (lesson 5.7).

Terminal
$ git switch main
Switched to branch 'main'
Your branch is up to date with 'origin/main'.

The Windows section of the installation guide is gone from disk now, and will be back the moment you switch to docs/12-… again.

Why this makes branches safe

  • Creating a branch is instant and changes nothing.
  • Committing on a branch cannot affect main or any other branch; only your label moves.
  • Deleting a branch removes a label. The commits stay until nothing points at them, and even then remain recoverable for a while (lesson 12.5). Git refuses to delete a branch whose commits are not merged anywhere unless you force it.
  • Switching rewrites files to a known snapshot; nothing committed is ever lost by switching.

Common mistakes

  • Thinking "the file was deleted" after a switch. It exists on the other branch. Switch back or git log --all -- <file>.
  • Committing on the wrong branch because the label you thought you were on was not HEAD ->. Read the git status first line (lesson 12.7 fixes it).
  • Expecting a branch to "contain" its history separately. Branches share commits; git log main..docs/12 shows only the commits the branch adds (lesson 6.5).

Try it yourself

Goal: watch a label move.

  1. In the playground, run git log --oneline --graph --all --decorate -3 and note where main is.
  2. Create a branch: git switch -c docs/practice-branch, then run the same log: both labels on one commit.
  3. Make an empty commit: git commit --allow-empty -m "docs: practice"; run the log again.
  4. Run cat .git/refs/heads/main and cat .git/refs/heads/docs/practice-branch.

Expected result: after step 3 the branch label is one commit ahead of main; the two files in step 4 contain different hashes, the second matching the newest commit.

Show solution

The branch files are the labels. main's file still holds the older hash because no commit was made on main. Switch back with git switch main and delete the practice branch with git branch -D docs/practice-branch (capital D because its commit is not merged).

Check yourself

1. What does git switch -c docs/12-windows-install-steps create?
2. After committing on branch docs/12, what happened to main?
3. You switch to another branch and a file you were working on disappears from the folder. What is true?

Key terms

Branch HEAD Ref Commit main