git branch
Branches are pointers to commits — cheap to create, easy to switch, foundational to every git workflow. Master checkout, switch, branch naming, merging, and pruning, and the rest of git (rebase, cherry-pick, worktrees) clicks into place.
Create, switch, rebase, prune, conventions
EXAMPLE
# 1) Create + switch
git branch # list local branches
git branch -a # local + remote
git branch feat/login # create from current HEAD
git branch feat/login main # create from main
git switch feat/login # modern (Git 2.23+)
git switch -c feat/login # create + switch
git checkout feat/login # legacy form (still works)
git checkout -b feat/login # create + switch (legacy)
# 2) Branch from a specific commit / tag
git switch -c hotfix/123 v1.2.3
git switch -c hotfix/123 abc1234
# 3) Show what changed on this branch vs main
git log main..HEAD --oneline # commits on this branch only
git diff main...HEAD # net diff vs main
git log --graph --oneline --all -n 20 # visualise
# 4) Rename
git branch -m new-name # rename current
git branch -m old-name new-name # rename specific
git push origin :old-name new-name # push rename to remote (delete old + push new)
git push origin -u new-name # set upstream
# 5) Delete
git branch -d feat/login # safe — refuses if unmerged
git branch -D feat/login # FORCE delete (lose work if unmerged)
git push origin --delete feat/login # delete on remote
# 6) Track remotes
git branch -u origin/main # set upstream
git branch --unset-upstream # detach
git fetch --prune # remove deleted remote branches from your local view
git remote prune origin # clean stale remote-tracking refs
# 7) Merging (the default integration path)
git switch main
git merge feat/login # creates a merge commit
git merge --ff-only feat/login # fast-forward only; fails if diverged
git merge --no-ff feat/login # always create merge commit (even if FF possible)
git merge --squash feat/login # bring changes as ONE commit; you commit separately
# 8) Rebasing (alternative integration)
git switch feat/login
git fetch origin
git rebase origin/main # replay my commits on top of origin/main
git rebase --abort # bail out if it gets messy
git rebase --continue # after resolving conflicts
git rebase -i HEAD~5 # interactive — squash, edit, reorder, drop
# Rebase produces a linear history; merge preserves the actual graph. Pick one per team and stick to it.
# 9) Cherry-pick — take a specific commit from another branch
git cherry-pick abc1234
git cherry-pick abc1234..def5678 # range
git cherry-pick --no-commit abc1234 # stage but don't commit
# 10) Stash before switching with dirty changes
git stash push -m 'wip: button styling'
git switch hotfix/issue-1
git stash list
git stash pop # apply + drop
git stash apply stash@{2} # apply specific without dropping
# 11) Compare branches
git log feat/login..feat/profile --oneline # commits in profile but not login
git diff feat/login feat/profile # full diff
git cherry feat/login feat/profile # quick view of unique commits
# 12) Naming conventions
# feat/short-desc — new feature
# fix/short-desc — bug fix
# chore/short-desc — tooling, deps, docs
# hotfix/incident-id — urgent production fix
# release/1.2.0 — release branch
# docs/short-desc — documentation
# spike/short-desc — exploration; deleted after
# Avoid: very long names, special chars, numbers-only, mixed case.
# 13) Branching strategies — pick one
# Trunk-based — short-lived branches, deploy from main daily
# GitFlow — main + develop + feature + release + hotfix (heavy)
# GitHub Flow — main + feature branches; PR to merge (light)
# Most modern teams: GitHub Flow + protected main + required reviews + CI.
# 14) Worktrees — multiple branches checked out at once
git worktree add ../my-app-hotfix hotfix/issue-1
# Now ../my-app-hotfix is a fully checked-out workspace for that branch — no stashing required.
git worktree list
git worktree remove ../my-app-hotfix
# 15) Common bugs
# • git branch -D on unmerged work — gone unless you find the dangling commit via reflog
# • Stale local branches piling up — git fetch --prune + git branch --merged | xargs -n1 git branch -d
# • Rebasing PUBLIC branches — rewrites history; rebases local only
# • Switching with uncommitted changes that conflict — git refuses; stash first
# • Wrong base for new branch — switch -c feat/x main always; check git status
# • git push -f after a rebase — fine on personal branches; on shared branches, communicate first
# • Forgetting to push the new branch — first push: git push -u origin feat/x
# • Mixing rebase and merge in the same PR — confusing history; pick one workflow per repo
Why it matters
Branches are pointers, not folders — create freely, switch with git switch, delete with -d (safe) or -D (force). Standardise on one integration style (merge or rebase), prune stale remotes regularly, and reach for worktrees when you need two branches checked out without stashing.
Tip: Tweak the snippet with Try it Yourself », then sit the quiz at the bottom of the page.
Example
Example
git branch # list git branch -d feature # delete git branch -m old new # renameTry it Yourself »
Exercise
Modern "create and switch to a new branch" command.
git
-c feature/login
Six letters.
Discussion
Loading…