Git Branching and Merging
Branches let you develop features in isolation without breaking the main codebase. Understanding branching and merging is essential for any team using Git.
Why Branch?
main: A --- B --- C ----------- G (merge)
\ /
feature: D --- E --- F
mainstays stable and deployable- Feature work happens on separate branches
- Merge when the feature is complete and tested
Branch Commands
# List branches (* = current)
git branch
# Create a branch
git branch feature/login
# Switch to a branch
git checkout feature/login
# Create and switch in one command
git checkout -b feature/login
# Modern equivalent (Git 2.23+)
git switch -c feature/login
# Delete a merged branch
git branch -d feature/login
# Force delete unmerged branch
git branch -D feature/login
# Rename current branch
git branch -m new-name
A Complete Feature Workflow
# Start from updated main
git checkout main
git pull origin main
# Create feature branch
git checkout -b feature/user-profile
# Work and commit
git add src/profile.js
git commit -m "Add profile page component"
git add src/profile.test.js
git commit -m "Add profile page tests"
# Push branch to remote
git push -u origin feature/user-profile
Open a Pull Request on GitHub/GitLab for code review.
Merging
# Merge feature into main
git checkout main
git pull origin main
git merge feature/user-profile
git push origin main
Git creates a merge commit when histories diverged:
Merge branch 'feature/user-profile'
Fast-Forward Merge
When main has no new commits since the branch was created, Git simply moves the pointer forward — no merge commit needed.
git merge feature/quick-fix
# Fast-forward
Merge Conflicts
Conflicts occur when the same lines were changed in both branches:
<<<<<<< HEAD
const greeting = "Hello";
=======
const greeting = "Hi there";
>>>>>>> feature/login
Resolve manually:
- Edit the file to keep the correct code
- Remove conflict markers (
<<<<,====,>>>>) - Stage and commit:
git add src/app.js
git commit -m "Resolve merge conflict in app.js"
Tools to help:
git mergetool # launch configured merge tool
git diff --name-only --diff-filter=U # list conflicted files
Rebase
Rebase replays your commits on top of another branch — cleaner linear history:
git checkout feature/login
git rebase main
Before:
main: A --- B --- C
\
feature: D --- E
After rebase:
main: A --- B --- C
\
feature: D' --- E'
Golden rule: Never rebase commits that have been pushed and shared with others (unless the team agrees).
Interactive rebase to clean up commits:
git rebase -i HEAD~3
# pick, squash, reword commits in editor
Branching Strategies
GitHub Flow (Simple)
mainis always deployable- Feature branches merge via Pull Request
- Deploy from
mainafter merge
Best for: web apps, continuous deployment teams.
Git Flow (Structured)
main— production releasesdevelop— integration branchfeature/*— new featuresrelease/*— release preparationhotfix/*— emergency production fixes
Best for: scheduled releases, mobile apps.
Trunk-Based Development
- Short-lived branches (< 1 day)
- Frequent merges to
main - Feature flags hide incomplete work
Best for: high-velocity teams with strong CI/CD.
Remote Branches
# List remote branches
git branch -r
# Fetch without merging
git fetch origin
# Pull = fetch + merge
git pull origin main
# Pull with rebase
git pull --rebase origin main
# Delete remote branch
git push origin --delete feature/login
Stashing Before Switching
Uncommitted work when you need to switch branches:
git stash push -m "WIP login form"
git checkout main
# ... do other work ...
git checkout feature/login
git stash pop
What Comes Next
Learn Advanced Git for cherry-pick, hooks, and bisect, then Collaboration for Pull Requests and code review workflows.