Skip to main content

Branches Explained 🌳

Branches are one of Git's most powerful features. They allow parallel development, experimentation, and organized workflows. Let's master them!

What is a Branch? πŸ”€β€‹

A branch is an independent line of development. Think of it as creating a copy of your project where you can make changes without affecting the main code.

main:    o──o──o──o (stable code)

feature: └──o──o──o (your new feature)

Each branch points to a specific commit, and you can switch between branches to work on different features simultaneously.

Creating Branches​

List Branches​

# List local branches
git branch

# Output example:
# * main
# feature-login
# bugfix-typo

# The * indicates current branch

# List all branches (including remote)
git branch -a

# List remote branches
git branch -r

Create a New Branch​

# Create branch (doesn't switch to it)
git branch feature-new-ui

# Create and switch in one command
git checkout -b feature-new-ui

# Modern way (Git 2.23+)
git switch -c feature-new-ui

Delete a Branch​

# Delete local branch
git branch -d feature-new-ui

# Force delete (even if not merged)
git branch -D feature-new-ui

# Delete remote branch
git push origin --delete feature-new-ui

Switching Between Branches​

Checkout (Traditional Way)​

# Switch to existing branch
git checkout main

# Switch and create branch
git checkout -b feature-auth

Switch (Modern Way - Git 2.23+)​

# Switch to branch
git switch main

# Switch and create branch
git switch -c feature-auth

# Go back to previous branch
git switch -

What Happens When You Switch?​

Before switch:
my-project/
β”œβ”€β”€ file1.js (version from main)
β”œβ”€β”€ file2.js
└── README.md

git switch feature

After switch:
my-project/
β”œβ”€β”€ file1.js (version from feature)
β”œβ”€β”€ file2.js
└── README.md

Files update to match the branch!

Branching Strategies πŸ“Šβ€‹

Git Flow (Complex Projects)​

Perfect for projects with scheduled releases:

main    ──o──o──o──o  (production-ready)
↑ ↓
└────────merge

develop ──o──o──o──o (development)
↑ β†— ↓
β”‚ / release-1.0.0
└─o────o (release prep)

feature-auth ──o──o──o (features)
feature-ui ──o──o
bugfix-typo ──o

Branches:

  • main - Production code only
  • develop - Integration branch
  • feature/* - New features
  • release/* - Release preparation
  • bugfix/* - Bug fixes

Workflow:

# Create feature from develop
git checkout develop
git checkout -b feature/user-auth

# Work on feature
git add .
git commit -m "Add user authentication"

# Create pull request to develop
# After review: merge to develop

# When ready for release
git checkout -b release/1.0.0
# Fix release issues only

# Merge to main and develop
git checkout main
git merge release/1.0.0
git tag v1.0.0

GitHub Flow (Simple & Fast)​

Perfect for continuous deployment:

main   ──o──o──o  (always deployable)
↓ ↓ ↓
└─┬ └─┬ └─── feature branches
β”‚ β”‚
↓ ↓ (merge via PR)
main branches

Branches:

  • main - Always production-ready
  • feature/* - Short-lived feature branches

Workflow:

# Create feature branch
git checkout -b feature/dark-mode

# Work and commit
git add .
git commit -m "Add dark mode support"

# Push to remote
git push origin feature/dark-mode

# Create pull request on GitHub
# Review and merge
# Delete branch

# Pull latest main
git checkout main
git pull origin main

Trunk-Based Development (Rapid Deployment)​

For teams doing frequent deployments:

main  ──o──o──o──o──o──o  (many small commits)

Principles:

  • All developers commit to main frequently (daily)
  • Short-lived feature branches (if any)
  • Feature flags for incomplete features
  • Continuous integration & testing

Merging Branches​

Fast-Forward Merge​

When target branch hasn't changed:

main:      o──o──o
└──o──o feature

git merge feature

Result (no new commit):
main: o──o──o──o──o

Command:

git checkout main
git merge feature

# Result: Fast-forward merge
# Branch pointer just moves forward

Regular Merge (Merge Commit)​

When both branches have new commits:

main:      o──o──o──────o  (merge commit)
└──o──o──oβ”€β”˜

Command:

git checkout main
git merge feature

# Git creates a merge commit
# Preserves branch history
# Both parent commits visible

Preventing Fast-Forward​

# Force merge commit even if possible
git merge --no-ff feature

# Creates merge commit with message
# Helpful for feature tracking

Handling Merge Conflicts βš οΈβ€‹

Conflicts occur when Git can't automatically merge changes.

What Causes Conflicts?​

Same file, same location, different changes:

main: Edit line 5: "Welcome!"
feature: Edit line 5: "Hello there!"

Result: CONFLICT

Resolving Conflicts​

Step 1: See conflicted files

git status
# Output:
# Both modified: app.js
# Both added: config.json

Step 2: View conflict markers

<<<<<<< HEAD
Welcome!
=======
Hello there!
>>>>>>> feature

# HEAD section = your current branch
# feature section = incoming branch
# Choose which to keep

Step 3: Resolve

# Edit file manually
# Remove markers
# Keep desired version

# Result:
Welcome and Hello!

# Or choose one completely:
Welcome!

Step 4: Complete merge

git add app.js
git commit -m "Merge feature: resolve conflicts"

Conflict Resolution Strategies​

# Keep your version entirely
git checkout --ours app.js

# Keep their version entirely
git checkout --theirs app.js

# Abort merge and start over
git merge --abort

Rebasing Branches πŸ”„β€‹

Rebase re-applies commits onto a new base. It rewrites historyβ€”use carefully!

Basic Rebase​

Before:
main: o──o──o
└──o──o feature

git switch feature
git rebase main

After:
main: o──o──o
└──o──o feature

# Same commits, but on new base

When to use: Cleaning up local branches before pushing When NOT to use: Branches already pushed to shared repository

Interactive Rebase​

Edit, reorder, squash, or drop commits:

# Rebase last 3 commits
git rebase -i HEAD~3

# Opens editor:
# pick a1b2c3d Add auth
# pick x1y2z3d Fix typo
# pick m1n2o3p Add tests

# Change to:
# pick a1b2c3d Add auth
# squash x1y2z3d Fix typo
# reword m1n2o3p Add comprehensive tests

# Result: 2 commits, second one renamed

Rebase vs Merge​

AspectMergeRebase
HistoryPreserves branchingRewrites, linear
CommitsCreates merge commitRe-applies existing
Shared branchesSafeDangerous
ReadabilityShows all activityCleaner history
Use caseShared branchesLocal cleanup

Remote Branches πŸŒβ€‹

Tracking Remote Branches​

# Create local branch tracking remote
git checkout --track origin/feature-auth

# Shorthand (auto-creates with same name)
git checkout feature-auth

# Set upstream for existing branch
git branch -u origin/feature-auth

Pull and Merge​

# Pull = fetch + merge
git pull origin main

# Equivalent to:
git fetch origin main
git merge origin/main

# Pull with rebase instead
git pull --rebase origin main

Push Branches​

# Push to remote with same name
git push origin feature-auth

# Set upstream while pushing
git push -u origin feature-auth

# Push all branches
git push origin --all

# Delete remote branch
git push origin --delete feature-auth

Branching Best Practices πŸŽ―β€‹

Naming Conventions​

# Good branch names:
feature/user-authentication
feature/dark-mode-support
bugfix/login-button-crash
hotfix/critical-security-issue
docs/api-documentation
refactor/database-layer

# Clear pattern: type/description

# Avoid:
fix1, new-stuff, temp, asdfghjkl

Branch Hygiene​

# Delete merged branches regularly
git branch -d feature-auth

# List merged branches
git branch --merged

# Delete all merged branches
git branch --merged | grep -v "*" | xargs git branch -d

Keep Branches Updated​

# Fetch latest changes
git fetch origin

# Rebase on latest main
git rebase origin/main

# Or merge latest main
git merge origin/main

Review Before Merge​

Always use pull requests:

git push origin feature-auth

# Create PR on GitHub
# Wait for review
# Address feedback
# Then merge

Common Branching Workflows​

Feature Branch Workflow​

# 1. Create feature branch
git checkout -b feature/new-api-endpoint

# 2. Make changes
git add .
git commit -m "Add new API endpoint"

# 3. Push branch
git push origin feature/new-api-endpoint

# 4. Create pull request
# (on GitHub)

# 5. After approval, merge
git checkout main
git pull origin main
git merge feature/new-api-endpoint

# 6. Delete branch
git branch -d feature/new-api-endpoint
git push origin --delete feature/new-api-endpoint

Hotfix Workflow​

# Critical bug in production!

# 1. Create hotfix from main
git checkout main
git checkout -b hotfix/critical-security-issue

# 2. Fix the bug
git add .
git commit -m "Fix critical security issue"

# 3. Merge to main
git checkout main
git merge --no-ff hotfix/critical-security-issue
git tag v1.0.1

# 4. Also merge to develop
git checkout develop
git merge --no-ff hotfix/critical-security-issue

# 5. Delete hotfix
git branch -d hotfix/critical-security-issue

Advanced Scenarios​

Recovering Deleted Branch​

# See recent HEAD positions
git reflog

# Find the commit you deleted
# a1b2c3d HEAD@{5}: commit: Last commit on deleted branch

# Recreate branch from that commit
git checkout -b feature-recovered a1b2c3d

Moving Commits Between Branches​

# Oops! Committed to main instead of feature

# Find commit hash
git log

# Create feature branch at current location
git branch feature-fix

# Reset main to previous commit
git reset --hard HEAD~1

# Work continues on feature-fix
git checkout feature-fix

Now you understand branches! Next, learn about Diff, Stash & Tags for more advanced workflows. πŸš€

Next: Diff, Stash & Tags