Git Branching & Merging
Branching is Git’s killer feature. Create branches in milliseconds, experiment freely, and merge with confidence.
Why Branching Matters
Parallel Development Multiple features in progress simultaneously without interference
Safe Experimentation Try ideas without risking the main codebase
Code Review Review changes before merging to main
Clean History Organize work into logical units
Understanding Branches
A branch is just a pointer to a commit. That’s it!
# List all branches
git branch
# List with last commit
git branch -v
# List all branches (including remote)
git branch -a
Creating Branches
# Create a new branch
git branch feature/user-auth
# Create and switch to it
git checkout -b feature/user-auth
# Modern syntax (Git 2.23+)
git switch -c feature/user-auth
Switching Branches
# Switch to existing branch
git checkout main
# or
git switch main
# Switch to previous branch
git checkout -
Before switching branches : Commit or stash your changes! Git won’t let you switch if you have uncommitted changes that would be overwritten.
Branch Naming Conventions
# Feature branches
git checkout -b feature/add-login
git checkout -b feature/payment-integration
# Bug fixes
git checkout -b fix/login-timeout
git checkout -b fix/memory-leak
# Hotfixes (urgent production fixes)
git checkout -b hotfix/security-patch
# Release branches
git checkout -b release/v1.2.0
# Experimental
git checkout -b experiment/new-architecture
Merging Branches
Fast-Forward Merge
When there are no new commits on the target branch:
# On main branch
git checkout main
# Merge feature branch
git merge feature/user-auth
Before:
main: A---B
\
feature: C---D
After (fast-forward):
main: A---B---C---D
Three-Way Merge
When both branches have new commits:
git checkout main
git merge feature/user-auth
Before:
main: A---B---E
\
feature: C---D
After (merge commit):
main: A---B---E---M
\ /
feature: C---D
Resolving Merge Conflicts
Conflicts happen when the same lines are changed in both branches.
Example Conflict
git merge feature/redesign
# Auto-merging index.html
# CONFLICT (content): Merge conflict in index.html
# Automatic merge failed; fix conflicts and then commit the result.
Conflict Markers
<<<<<<< HEAD
< h1 > Welcome to My Site </ h1 >
=======
< h1 > Welcome to Our Platform </ h1 >
>>>>>>> feature/redesign
<<<<<<< HEAD: Your current branch’s version
=======: Separator
>>>>>>> feature/redesign: Incoming branch’s version
Resolving
Open the conflicted file
# See which files have conflicts
git status
Edit the file
Remove conflict markers and choose the correct version: < h1 > Welcome to Our Platform </ h1 >
Complete the merge
git commit # Message pre-filled
# Use a visual merge tool
git mergetool
# Abort the merge
git merge --abort
# See conflicts
git diff --name-only --diff-filter=U
Deleting Branches
# Delete a merged branch
git branch -d feature/user-auth
# Force delete (even if not merged)
git branch -D experiment/failed-idea
# Delete remote branch
git push origin --delete feature/user-auth
Branch Management
Viewing Branches
# Branches merged into current branch
git branch --merged
# Branches not yet merged
git branch --no-merged
# Branches with last commit info
git branch -vv
Renaming Branches
# Rename current branch
git branch -m new-name
# Rename another branch
git branch -m old-name new-name
Common Branching Workflows
Feature Branch Workflow
# 1. Create feature branch from main
git checkout main
git pull origin main
git checkout -b feature/add-comments
# 2. Work on feature
# ... make changes ...
git add .
git commit -m "feat: add comment system"
# 3. Keep feature branch updated
git checkout main
git pull origin main
git checkout feature/add-comments
git merge main # Or rebase
# 4. Push and create pull request
git push origin feature/add-comments
# Create PR on GitHub/GitLab
# 5. After PR is merged, clean up
git checkout main
git pull origin main
git branch -d feature/add-comments
Gitflow Workflow
# Main branches: main (production), develop (integration)
# Start a feature
git checkout develop
git checkout -b feature/new-feature
# Finish feature
git checkout develop
git merge --no-ff feature/new-feature
git branch -d feature/new-feature
# Start a release
git checkout -b release/1.2.0 develop
# ... version bumps, bug fixes ...
git checkout main
git merge --no-ff release/1.2.0
git tag -a v1.2.0
git checkout develop
git merge --no-ff release/1.2.0
git branch -d release/1.2.0
# Hotfix
git checkout -b hotfix/1.2.1 main
# ... fix ...
git checkout main
git merge --no-ff hotfix/1.2.1
git tag -a v1.2.1
git checkout develop
git merge --no-ff hotfix/1.2.1
git branch -d hotfix/1.2.1
Trunk-Based Development
# Everyone works on main or very short-lived branches
git checkout main
git pull origin main
git checkout -b quick-fix
# ... make changes ...
git commit -am "fix: resolve login issue"
git push origin quick-fix
# Immediate merge after CI passes
Merge Strategies
Merge (Default)
git merge feature/new-ui
# Creates a merge commit
Pros : Preserves complete history
Cons : Can create a messy history with many merge commits
Squash Merge
git merge --squash feature/new-ui
git commit -m "feat: add new UI design"
# Combines all feature commits into one
Pros : Clean history
Cons : Loses individual commit history
Rebase (Advanced)
git checkout feature/new-ui
git rebase main
# Replays feature commits on top of main
Pros : Linear history
Cons : Rewrites history (don’t rebase public branches!)
Practical Examples
Example 1: Feature Development
# Start feature
git checkout -b feature/dark-mode
# Make commits
echo "dark theme CSS" > dark.css
git add dark.css
git commit -m "feat: add dark mode styles"
echo "toggle button" > toggle.js
git add toggle.js
git commit -m "feat: add dark mode toggle"
# Merge to main
git checkout main
git merge feature/dark-mode
# Clean up
git branch -d feature/dark-mode
Example 2: Handling Conflicts
# Create conflict scenario
git checkout -b branch-a
echo "Version A" > file.txt
git add file.txt
git commit -m "Add version A"
git checkout main
git checkout -b branch-b
echo "Version B" > file.txt
git add file.txt
git commit -m "Add version B"
# Try to merge
git checkout main
git merge branch-a # Success
git merge branch-b # CONFLICT!
# Resolve
# Edit file.txt, choose version
git add file.txt
git commit
# Clean up
git branch -d branch-a branch-b
Best Practices
Keep Branches Short-Lived
Merge within days, not weeks
Reduces merge conflicts
Easier code review
git pull origin main
# Resolve any conflicts
git push origin feature/my-feature
# Local
git branch -d feature/completed
# Remote
git push origin --delete feature/completed
✅ feature/user-authentication
✅ fix/login-timeout
❌ my-branch
❌ test
Troubleshooting
”Cannot switch branches - uncommitted changes"
# Option 1: Commit changes
git add .
git commit -m "WIP: work in progress"
# Option 2: Stash changes
git stash
git checkout other-branch
git stash pop
"Merge conflict in binary file"
# Choose theirs
git checkout --theirs file.png
git add file.png
# Choose ours
git checkout --ours file.png
git add file.png
"Accidentally committed to wrong branch”
# Move commit to correct branch
git checkout correct-branch
git cherry-pick abc123 # SHA of the commit
# Remove from wrong branch
git checkout wrong-branch
git reset --hard HEAD~1
Key Takeaways
Branches are lightweight pointers
Create branches freely for features, fixes, experiments
Merge conflicts are normal—learn to resolve them
Delete branches after merging
Choose a workflow that fits your team
Next: Git Collaboration →