Section 2 · Branching and Merging
Branches Are Pointers, HEAD Is You
15 min4 min readFill in the blanks
Lesson at a glance
Create, switch, rename and delete branches knowing that each is a movable pointer to a commit, and recover cleanly from a detached HEAD.
- 1A branch is a sticky note
- 2Making and moving between branches
- 3Housekeeping
- 4Borrowing one file from another branch
- 5Detached HEAD
No video here — just the real thing: a written lesson, runnable examples, a quiz and practice.
In older version control systems a branch was a full copy of the project, slow to make and painful to combine, so people avoided them. In Git a branch costs almost nothing. That changes how you work: every idea, fix or experiment on your portfolio can get its own branch, and throwing one away is as cheap as making it.
A branch is a sticky note
Look inside your repository:
cat .git/refs/heads/mainc39be1142d6f0a8e7b1c5d93e2f4a0b6c8d7e912That’s the whole main branch: a file containing one commit ID. A branch is a named, movable pointer to a commit. The history behind it isn’t stored in the branch; it’s found by following parent links from that commit, as you did in the last lesson.
So how does Git know which branch you’re on? Another small file:
cat .git/HEADref: refs/heads/mainHEAD is a pointer to a pointer. It normally names a branch, and that branch names a commit. When you commit, Git creates the new commit with the current one as its parent, then moves the branch HEAD names to the new commit. HEAD itself doesn’t change; it’s still “on main”, and main has moved forward.
You don’t need to read these files day to day (in older or busier repositories, branch IDs may be packed into .git/packed-refs instead), but seeing them once removes the mystery. Everything in this section is about moving these sticky notes around a graph.
Making and moving between branches
Your next portfolio change is a site footer. Give it a branch:
git switch -c footerSwitched to a new branch 'footer'-c creates the branch at your current commit and switches to it. The two-step version is git branch footer followed by git switch footer. Now commit some work:
git add index.html styles.css
git commit -m "Add site footer with contact links"main is untouched. Switch back and the footer disappears from your files; switch to footer again and it returns:
git switch main # working tree now matches main's snapshot
git switch footer # and now footer's
git switch - # back to whichever branch you were on beforeSwitching rewrites the files in your working tree to match the target snapshot. Uncommitted changes come along if they don’t clash with the target. If they would be overwritten, Git refuses to switch and tells you to commit or stash first. That refusal is protecting you; don’t look for a way around it. Commit the work, or wait for the stash lesson in section 4.
Housekeeping
git branch # list local branches; * marks the current one
git branch -v # with the commit each points to
git branch -m footer site-footer # rename
git branch -d site-footer # delete, only if its work is merged
git branch -D experiment # force-delete, merged or not-d refuses to delete a branch whose commits aren’t merged into your current branch (or into the branch’s upstream, once it has one), which is a useful safety net. -D skips the check. Use it only when you’re sure the work is unwanted.
Name branches for what they do: footer, fix-mobile-nav, projects-grid. Many teams add a prefix such as feat/ or fix/; slashes are allowed in branch names.
Borrowing one file from another branch
Sometimes you want one file from another branch without the rest of its work. git restore can read from any commit:
git restore --source=dark-mode styles.cssThat overwrites styles.css in your working tree with the version on dark-mode. Check it with git diff, then stage and commit it on your current branch. You’ll still see older tutorials use git checkout for both switching and restoring; Git 2.23 split those two jobs into git switch and git restore, which are harder to confuse.
Detached HEAD
You can point HEAD straight at a commit instead of a branch, to look at an old version of the site:
git switch --detach a1c9d72Git warns you’re in detached HEAD state. Looking around is perfectly safe. The risk is committing there: new commits belong to no branch, so when you switch away, nothing points at them and they quietly drop out of git log.
Your footer branch is ready and main hasn’t moved. Next you’ll bring the two together with a merge.
Key takeaways
- A branch is a tiny file holding one commit ID; creating one copies nothing and takes milliseconds.
- HEAD names the branch you’re on, and each new commit moves that branch forward while HEAD comes along.
git switch -c <name>creates a branch at the current commit and switches to it in one step.- A detached HEAD points straight at a commit; save any work made there with
git switch -c <name>before leaving. git restore --source=<branch> <file>copies one file from another branch without switching to it.