Branches — parallel timelines
A branch is a named pointer to a commit. Cheap to create, cheap to delete. You branch off `main` to work on a feature, then merge back when done.
A branch is a file in .git/refs/heads/<name> containing a 40-char SHA — the commit it points to. Creating a branch is O(1): just write a ref. Compare to centralized VCS where a branch is a server-side directory copy. This is why Git branches are 'cheap'.
HEAD: a symbolic ref at .git/HEAD storing ref: refs/heads/<current-branch>. Detached HEAD = HEAD directly contains a SHA, not a ref. Happens on git checkout <sha>. Commits made in detached HEAD are reachable only via reflog until you create a branch from them.
switch vs checkout: git switch (Git 2.23+) is the modern, focused command for branch operations. git checkout is the legacy umbrella that also handles file restoration (now git restore). Prefer switch/restore in tutorials and scripts; both still work.
Tracking branches: a local branch can track a remote branch (git branch --set-upstream-to=origin/main main or -u shorthand on push). Once tracking, git push and git pull know where to go without explicit args. git status reports 'ahead by N, behind by M'.
Merged vs unmerged delete: git branch -d refuses to delete a branch whose tip isn't reachable from another branch — saving you from losing commits. -D (capital) forces deletion. Use git reflog to recover commits from a force-deleted branch.
Default branch: main (modern), master (legacy). Change locally with git branch -m old new then push the rename and update upstream defaults on GitHub. Renaming the default branch on a public repo breaks deep links and CI configs that hardcode the name.
Practice
Type the command that creates a new branch `feature/login` AND switches to it.
Practice
Type the command to safely delete the local branch `old-feature` (refuse if commits would be lost).
Grounded on https://git-scm.com/book/en/v2/Git-Branching-Branches-in-a-Nutshell
Next up
Merge vs rebase
Two ways to integrate changes from one branch into another. Merge preserves history as it happened (with a merge commit). Rebase rewrites your branch on top of another, producing a linear history.