Creating and Switching Branches in Git
Branching is Git’s superpower. It lets you create isolated lines of development so you can experiment, fix bugs, or build features without disturbing the stability of the main code line. Mastering how to create and switch branches efficiently is foundational to any effective Git workflow.
1. Why Branches Exist (Mental Model)
Think of the main (or master) branch as the published history of your project. A branch is simply a movable pointer to a commit. When you create a new branch, you are saying: “From this point in history, I want to start a new line of work.” Nothing is copied; Git just creates a lightweight reference.
Key ideas:
- A branch points to a commit.
- Your
HEADtells you which branch (or commit) you are “on.” - When you commit on a branch, the branch pointer moves forward.
Because branches are cheap, you should use them generously: one branch per feature, per bug fix, per experiment.
2. Listing and Understanding Current Branches
To see existing branches locally:
$ git branchThe current branch is marked with an asterisk. To see both local and remote branches:
$ git branch -aTo see what each branch points to along with last commit info:
$ git branch -vIf you want to clean up stale remote-tracking branches (references to branches deleted on the remote):
$ git fetch --prune3. Creating a New Branch
You typically create a branch from the latest state of another branch (often main). First ensure you are up to date:
$ git checkout main
$ git pull origin mainNow create a branch:
$ git branch feature/login-formThis creates it but does not switch you to it. To both create and switch immediately (preferred):
$ git switch -c feature/login-formOlder syntax (still valid):
$ git checkout -b feature/login-formNaming conventions matter. Use:
feature/<name>for new functionalitybugfix/<ticket-id>for fixeshotfix/<critical>for urgent production patcheschore/…,refactor/…, etc.
Avoid spaces, uppercase, and ambiguous names like new or temp.
4. Switching Between Branches
To switch to an existing branch:
$ git switch feature/login-formOr using older syntax:
$ git checkout feature/login-formGit will refuse to switch if you have uncommitted changes that would be overwritten. Options:
- Commit them.
- Stash them (
git stash push -m "WIP"). - Discard them (
git restore .).
To return to the previous branch quickly:
$ git switch -Detached HEAD State
If you checkout a specific commit (not a branch):
$ git checkout 4f2a9c1You enter “detached HEAD” mode. You can explore, build, or test, but if you make commits without creating a branch, those commits may become hard to find later. To preserve work:
$ git switch -c experiment/performance-tuning5. Keeping Your Branch Updated
While working on a feature branch, other commits may land on main. To incorporate them:
$ git switch feature/login-form
$ git fetch origin
$ git merge origin/mainThis creates a merge commit (if needed). For a linear history and if the branch is only yours:
$ git fetch origin
$ git rebase origin/mainRebasing rewrites your branch’s commits on top of the latest main tip. Do NOT rebase shared branches that others might be using; it changes commit hashes.
6. Pushing Your Branch to Remote
A branch exists only locally until you push it:
$ git push -u origin feature/login-form-u sets the upstream so future git push and git pull commands know the default remote branch.
To list tracking relationships:
$ git branch -vv7. Renaming a Branch
If the branch name is unclear or requirements changed:
If you are on the branch you want to rename (local):
$ git branch -m feature/login-form feature/auth-uiIf already pushed, delete the old name remotely and push the new:
$ git push origin :feature/login-form
$ git push -u origin feature/auth-uiSome hosting platforms offer a “rename” feature that handles redirects automatically—use that if available.
8. Deleting Branches
After merging (and once you’re sure it’s no longer needed): Local delete:
$ git branch -d feature/login-form-d is safe; it refuses if unmerged. To force (dangerous):
$ git branch -D feature/login-formRemote delete:
$ git push origin :feature/login-formOr the newer syntax:
$ git push origin --delete feature/login-formCleaning up reduces cognitive load.
9. Common Workflow Example (Feature Branch)
- Update main:
git switch main && git pull. - Create branch:
git switch -c feature/report-export. - Code + commit frequently with meaningful messages.
- Periodically rebase or merge
origin/mainto stay current. - Push:
git push -u origin feature/report-export. - Open a Pull Request (PR) / Merge Request (MR).
- After merge, delete local + remote branch.
This loop keeps history segmented by purpose and improves code review focus.
10. Troubleshooting Scenarios
| Situation | Cause | Resolution |
|---|---|---|
| Cannot switch branches | Uncommitted conflicting changes | Commit, stash, or restore files |
| Detached HEAD warning | Checked out a commit, not a branch | Create a branch with git switch -c new-branch |
| Branch missing after clone | Only default branch cloned | git fetch --all then git switch branch-name |
| Push rejected (non-fast-forward) | Remote advanced independently | git pull --rebase then re-push |
| Accidentally deleted branch | No reference exists | Recover via git reflog -> git branch recovered <commit> |
11. Using Branches Strategically
Branches are not just for features:
- Prototype explorations
- Hotfixes directly from release tags
- Long-running integration branches (use sparingly—consider trunk-based + feature flags instead)
- Documentation or infrastructure changes
Aim to keep feature branches short-lived. The longer a branch lives, the harder it is to merge cleanly.
12. Practice Exercise
- Clone or init a repo.
- Create
feature/colorsbranch and add a file. - Commit twice with meaningful messages.
- Rebase it onto an updated
mainafter adding an unrelated commit there. - Rename the branch to
feature/theme-colors. - Push and open a PR.
- Merge and delete branch locally and remotely.
Reflect: Which steps felt slow? Automate them with aliases or scripts (e.g., gco, gpl, gpsup).
13. Key Takeaways
- Branch creation is instant; use many small, focused branches.
switchis the modern, clearer command for changing branches.- Keep branches up to date proactively to minimize merge friction.
- Clean up after merges to maintain a tidy repository.
- Always create a branch before committing exploratory work.
Mastering branching sets the stage for advanced workflows like rebasing, interactive history editing, and multi-branch release strategies.
