Branching & Merging

Branches, merging, resolving conflicts

What Are Branches?

A branch is a parallel universe for your code. You can experiment, break things, and when you’re happy, merge it back. Main code stays safe.

main:     A ─── B ─── C ─── D ─── E
                       \           /
feature:                F ─── G ──

Creating Branches

See All Branches

# List local branches (* = current)
git branch

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

Create a New Branch

# Create branch
git branch feature-login

# Create and switch to branch (recommended)
git checkout -b feature-login

# Modern alternative (Git 2.23+)
git switch -c feature-login

Switch Between Branches

# Switch to existing branch
git checkout main

# Modern alternative
git switch main

Working with Branches

Typical Workflow

# 1. Start from main
git checkout main

# 2. Create feature branch
git checkout -b feature/user-profile

# 3. Make changes and commit
echo "Profile code" > profile.js
git add profile.js
git commit -m "Add user profile feature"

# 4. Make more commits as needed
echo "More code" >> profile.js
git commit -am "Enhance profile feature"

# 5. Switch back to main when done
git checkout main

See Branch Differences

# Compare branches
git diff main..feature/user-profile

# See commits in feature not in main
git log main..feature/user-profile --oneline

Merging Branches

Merging brings changes from one branch into another.

Basic Merge

# 1. Switch to target branch (usually main)
git checkout main

# 2. Merge feature branch into main
git merge feature/user-profile

# 3. Delete feature branch (optional)
git branch -d feature/user-profile

Merge Types

Fast-Forward Merge

When main hasn’t changed since you branched:

Before:
main:    A ─── B
              \
feature:       C ─── D

After (fast-forward):
main:    A ─── B ─── C ─── D

Three-Way Merge

When both branches have new commits:

Before:
main:    A ─── B ─── E
              \
feature:       C ─── D

After (merge commit):
main:    A ─── B ─── E ─── M
              \           /
feature:       C ─── D ──
# Force a merge commit (no fast-forward)
git merge --no-ff feature/user-profile

Resolving Conflicts

Conflicts happen when both branches change the same lines. Git can’t decide which to keep.

What Conflicts Look Like

>>>>>> feature/user-profile

Resolving Step by Step

# 1. Try to merge
git merge feature/user-profile
# CONFLICT (content): Merge conflict in app.js

# 2. See conflicted files
git status

# 3. Open and edit conflicted files
# Remove conflict markers, keep the code you want

# 4. Stage resolved files
git add app.js

# 5. Complete the merge
git commit -m "Merge feature/user-profile, resolve conflicts"

Abort a Merge

# Cancel merge and go back to before
git merge --abort

Deleting Branches

# Delete merged branch (safe)
git branch -d feature/user-profile

# Force delete unmerged branch (careful!)
git branch -D feature/abandoned

# Delete remote branch
git push origin --delete feature/user-profile

Branching Strategies

GitHub Flow (Simple)

Best for continuous deployment:

main ──────────────────────────────────
        \                    /
         feature-branch ────
  • main is always deployable
  • Create branch for each feature
  • Open PR, review, merge

Git Flow (Structured)

Best for scheduled releases:

main     ─────────────────────────────
            \                    /
develop  ────●─────────●────────●────
              \       / \      /
feature        ●─────●   ●────●
  • main - production releases
  • develop - integration branch
  • feature/* - new features
  • release/* - release prep
  • hotfix/* - production fixes

Quick Reference

# Branches
git branch                    # List branches
git branch <name>             # Create branch
git checkout -b <name>        # Create and switch
git checkout <name>           # Switch branch
git branch -d <name>          # Delete (safe)
git branch -D <name>          # Delete (force)

# Merging
git merge <branch>            # Merge into current
git merge --no-ff <branch>    # Force merge commit
git merge --abort             # Cancel merge

# Comparing
git diff <branch1>..<branch2>
git log <branch1>..<branch2>

Practice Exercise

# Setup
mkdir branch-practice && cd branch-practice
git init
echo "# Main Project" > README.md
git add . && git commit -m "Initial commit"

# Create and work on feature branch
git checkout -b feature/add-about
echo "About page content" > about.txt
git add . && git commit -m "Add about page"

# Go back to main and make a change
git checkout main
echo "Updated main" >> README.md
git commit -am "Update README"

# Merge feature branch
git merge feature/add-about

# View the result
git log --oneline --graph

# Cleanup
git branch -d feature/add-about