Listing Branches
Before creating or switching branches, it's useful to see which branches exist. The current branch is marked with *.
# List all local branches (* marks current branch)
git branch
# * main
# feature/login
# bugfix/navbar
# List local + remote-tracking branches
git branch -a
# * main
# feature/login
# remotes/origin/main
# remotes/origin/feature/login
# List branches with last commit info
git branch -v
# * main a1b2c3d Fix navbar padding
# feature/login 9f8e7d6 Add login form
Creating a Branch
git branch <name> creates a new branch pointing to the current commit but does NOT switch to it. You stay on your current branch.
# Create a new branch (stays on current branch)
git branch feature/login
# Create branch from a specific commit or tag
git branch hotfix/crash v2.1.0
git branch hotfix/crash a3f8c2d
# Verify it was created (without switching)
git branch
# * main β still on main
# feature/login β new branch exists
Common patterns: feature/description, bugfix/issue-123, hotfix/critical-bug, chore/update-deps, release/v2.0. Slashes create a visual grouping in GUIs and on GitHub. Avoid spaces β use hyphens or slashes instead.
Switching Branches
Use git switch to move to an existing branch. Git updates your working directory to match that branch's state.
# Modern way: git switch (Git 2.23+)
git switch feature/login
# Classic way: git checkout (still works, still common)
git checkout feature/login
# After switching, HEAD now points to feature/login
git branch
# main
# * feature/login
If you have uncommitted changes, Git may refuse to switch branches if those changes would be overwritten. Either commit your changes first, or use git stash to temporarily save them, switch branches, do your work, then git stash pop to restore them.
Create AND Switch (One Command)
The most common workflow is to create a branch and immediately switch to it. Both modern and classic commands offer a shorthand for this.
# Modern: git switch -c (create and switch)
git switch -c feature/user-profile
# Classic: git checkout -b (create and switch)
git checkout -b feature/user-profile
# Both commands do the same thing.
# Result: branch created, HEAD switched to it
git branch
# main
# * feature/user-profile
git switch over git checkout
git checkout is a Swiss Army knife β it does many things: switch branches, restore files, check out commits. This makes it confusing for beginners. git switch (added in Git 2.23) does only one thing: manage branches. Use git switch for branch operations and git restore for file operations. Your future self will thank you.
Deleting a Branch
After merging a feature branch, delete it to keep your branch list clean.
# Safe delete: only works if branch is fully merged
git branch -d feature/login
# Deleted branch feature/login (was a1b2c3d).
# Force delete: deletes even if NOT merged (use with care!)
git branch -D feature/experiment
# Deleted branch feature/experiment (was 9f8e7d6).
# Delete a remote-tracking branch
git push origin --delete feature/login
# You cannot delete the branch you're currently on
# Switch to another branch first:
git switch main
git branch -d feature/login
If you force-delete an unmerged branch, the commits on that branch become unreachable and will eventually be garbage-collected by Git. You can recover them within ~30 days using git reflog, but don't rely on it. Be certain you don't need those commits before using -D.
Renaming a Branch
# Rename a branch (while on a different branch)
git branch -m old-name new-name
# Rename the CURRENT branch
git branch -m new-name
# If the branch was already pushed to a remote,
# you need to delete the old remote branch and push the new one:
git push origin --delete old-name
git push origin new-name
git push -u origin new-name # set tracking
Quick Reference
| Task | Modern (preferred) | Classic |
|---|---|---|
| List branches | git branch | git branch |
| Create branch | git branch <name> | git branch <name> |
| Switch branch | git switch <name> | git checkout <name> |
| Create + switch | git switch -c <name> | git checkout -b <name> |
| Delete (safe) | git branch -d <name> | git branch -d <name> |
| Delete (force) | git branch -D <name> | git branch -D <name> |
| Rename | git branch -m old new | git branch -m old new |
π Summary
git branchβ list branches;-aincludes remote-tracking branches;-vshows last commit.git branch <name>β creates a branch without switching to it.git switch <name>β switch to a branch (modern);git checkout <name>is the classic equivalent.git switch -c <name>β create AND switch (modern);git checkout -bis the classic equivalent.git branch -d <name>β safe delete (merged branches only);-Dforce deletes.git branch -m old newβ rename a branch.- Prefer
git switchovergit checkoutfor branch operations β it does one thing clearly.
FAQ
git switch was introduced in Git 2.23 specifically to handle branch switching, making the command more predictable. git checkout predates it and handles many different tasks (switching branches, restoring files, checking out specific commits). Both work for branch operations, but git switch is clearer in intent and less error-prone. The Git team recommends using git switch for branch operations going forward.
Sometimes. If your uncommitted changes don't conflict with the files on the target branch, Git will carry them with you to the new branch. If there's a conflict (the target branch has a different version of a file you've modified), Git will refuse and ask you to commit or stash first. Use git stash to save your work temporarily, switch branches, work, then git stash pop to restore your changes.
No practical limit. Each branch is just a tiny file, so you can have thousands. However, having hundreds of active branches is a workflow smell β it suggests feature branches are living too long. A healthy practice is to keep branches short-lived (hours to days for features, minutes for hotfixes) and delete them after merging.
Yes, if you act quickly. Git keeps a log of recent HEAD movements in the reflog. Run git reflog to find the commit hash the branch was pointing to, then recreate it: git branch recovered-branch <hash>. The reflog entries expire after 30β90 days by default, so don't wait too long.