iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

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      # rename
Try it Yourself »

Exercise

Modern "create and switch to a new branch" command.

git -c feature/login

Discussion

Loading…