Skip to main content

Branching & Merging

Comprehensive guide to Git branching strategies, merging techniques, and branch management workflows.

Branch Basics

Creating Branches

# List branches
git branch # Local branches only
git branch -r # Remote branches only
git branch -a # All branches (local + remote)
git branch -v # Show last commit on each branch
git branch -vv # Show tracking branches

# Create branch
git branch feature-name # Create from current commit
git branch feature-name main # Create from specific branch
git branch feature-name <commit-hash> # Create from specific commit

# Create and switch (modern syntax)
git switch -c feature-name # Create and switch
git switch -c feature-name main # Create from main and switch

# Create and switch (traditional syntax)
git checkout -b feature-name # Create and switch
git checkout -b feature-name main # Create from main and switch

Switching Branches

# Switch branches (modern syntax - recommended)
git switch main
git switch feature-name
git switch - # Switch to previous branch

# Switch branches (traditional syntax)
git checkout main
git checkout feature-name
git checkout - # Switch to previous branch

# Switch with uncommitted changes
git switch -m feature-name # Move uncommitted changes to new branch
git stash # Stash changes first
git switch feature-name
git stash pop # Apply stashed changes

Branch Information

# Show current branch
git branch --show-current
git rev-parse --abbrev-ref HEAD

# Show branches with commit info
git branch -v
git branch -vv # Include tracking info

# Show merged/unmerged branches
git branch --merged # Branches merged into current
git branch --no-merged # Branches not merged into current
git branch --merged main # Branches merged into main

Deleting Branches

Local Branch Deletion

# Safe delete (only if merged)
git branch -d feature-name

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

# Delete multiple branches
git branch -d branch1 branch2 branch3

# Delete all merged branches (excluding main/master)
git branch --merged main | grep -v "main\|master" | xargs -n 1 git branch -d

Remote Branch Deletion

# Delete remote branch
git push origin --delete feature-name
git push origin :feature-name # Alternative syntax

# Delete remote tracking reference
git remote prune origin
git fetch --prune # Remove stale remote references

Merging Strategies

Basic Merging

# Merge branch into current branch
git merge feature-name

# Merge with custom message
git merge feature-name -m "Merge feature: add user authentication"

# Show what would be merged (dry run)
git merge --no-commit --no-ff feature-name
git diff --cached # Review changes
git merge --abort # Cancel if needed

Merge Types

# Fast-forward merge (default when possible)
git merge feature-name

# No fast-forward merge (always create merge commit)
git merge --no-ff feature-name

# Squash merge (combine all commits into one)
git merge --squash feature-name
git commit -m "Add feature: combined all commits"

# Fast-forward only (fail if not possible)
git merge --ff-only feature-name

Merge Conflict Resolution

# When merge conflicts occur
git merge feature-name
# Conflicts detected...

# View conflicted files
git status
git diff --name-only --diff-filter=U

# Resolve conflicts manually, then:
git add resolved-file.txt
git commit # Complete the merge

# Or abort the merge
git merge --abort

# Use merge tools
git mergetool
git mergetool --tool=vimdiff

Advanced Merge Options

# Merge with strategy
git merge -X theirs feature-name # Prefer their changes in conflicts
git merge -X ours feature-name # Prefer our changes in conflicts

# Merge specific files only
git checkout feature-name -- path/to/file.txt
git commit -m "Merge specific file from feature branch"

# Octopus merge (multiple branches)
git merge branch1 branch2 branch3

Branching Workflows

Feature Branch Workflow

# Start feature development
git switch main
git pull origin main
git switch -c feature/user-authentication

# Work on feature
git add .
git commit -m "Add login form"
git commit -m "Implement authentication logic"
git commit -m "Add tests for authentication"

# Keep feature branch updated
git switch main
git pull origin main
git switch feature/user-authentication
git merge main # or git rebase main

# Complete feature
git switch main
git merge feature/user-authentication
git push origin main
git branch -d feature/user-authentication

GitFlow Workflow

# Initialize GitFlow
git flow init

# Feature development
git flow feature start user-auth
# Work on feature...
git flow feature finish user-auth

# Release preparation
git flow release start 1.0.0
# Final testing and bug fixes...
git flow release finish 1.0.0

# Hotfix for production
git flow hotfix start security-fix
# Fix critical issue...
git flow hotfix finish security-fix

GitHub Flow

# Simple feature workflow
git switch main
git pull origin main
git switch -c feature/new-feature

# Work and push
git add .
git commit -m "Implement new feature"
git push -u origin feature/new-feature

# Create pull request on GitHub
# After review and approval, merge via GitHub interface

# Clean up locally
git switch main
git pull origin main
git branch -d feature/new-feature

Branch Management

Tracking Branches

# Set upstream for existing branch
git branch --set-upstream-to=origin/main main
git branch -u origin/main main # Short form

# Push and set upstream
git push -u origin feature-name

# View tracking relationships
git branch -vv

# Fetch and track new remote branch
git fetch origin
git switch -c feature-name origin/feature-name
git switch --track origin/feature-name # Modern syntax

Branch Comparison

# Compare branches
git diff main..feature-name # Changes in feature not in main
git diff main...feature-name # Changes since common ancestor
git log main..feature-name # Commits in feature not in main
git log --oneline main..feature-name # Compact format

# Show commits unique to each branch
git log --left-right --graph --cherry-pick --oneline main...feature-name

# Files changed between branches
git diff --name-only main..feature-name
git diff --stat main..feature-name

Branch Cleanup

# List branches by last commit date
git for-each-ref --sort=-committerdate refs/heads/ --format='%(committerdate:short) %(refname:short)'

# Delete merged feature branches
git branch --merged main | grep "feature/" | xargs -n 1 git branch -d

# Delete remote tracking branches for deleted remotes
git remote prune origin

# Clean up everything
git fetch --prune
git branch --merged main | grep -v "main\|master\|develop" | xargs -n 1 git branch -d

Rebasing vs Merging

When to Use Rebase

# Rebase feature branch onto main (clean history)
git switch feature-name
git rebase main

# Interactive rebase to clean up commits
git rebase -i HEAD~3

# Rebase when pulling (avoid merge commits)
git pull --rebase origin main

When to Use Merge

# Merge when you want to preserve branch history
git merge --no-ff feature-name

# Merge for shared/public branches
git merge feature-name

# Merge for completing features (clear integration points)
git merge feature-name -m "Merge feature: user authentication"

Advanced Branching

Temporary Branches

# Create temporary experiment branch
git switch -c experiment/try-new-approach

# Quick experiment
git add .
git commit -m "Try experimental approach"

# If successful, merge back
git switch main
git merge experiment/try-new-approach

# If unsuccessful, just delete
git branch -D experiment/try-new-approach

Branch from Specific Commit

# Create branch from specific commit
git branch feature-name abc123
git switch -c feature-name abc123

# Create branch from tag
git switch -c hotfix/v1.0.1 v1.0.0

# Create branch from remote commit
git switch -c feature-name origin/main~3

Orphan Branches

# Create branch with no history (for GitHub Pages, docs, etc.)
git switch --orphan gh-pages
git rm -rf .
echo "Hello World" > index.html
git add index.html
git commit -m "Initial GitHub Pages commit"

Best Practices

Branch Naming Conventions

# Feature branches
git switch -c feature/user-authentication
git switch -c feature/payment-integration
git switch -c feat/shopping-cart

# Bug fixes
git switch -c bugfix/login-error
git switch -c fix/memory-leak
git switch -c bug/csrf-validation

# Hotfixes
git switch -c hotfix/security-patch
git switch -c hotfix/critical-bug

# Releases
git switch -c release/v1.2.0
git switch -c release/2023-Q1

# Personal branches (if working in team)
git switch -c john/feature/user-auth
git switch -c jane/experiment/performance

Merge Strategy Guidelines

# Use fast-forward for simple updates
git merge feature-name # When history is linear

# Use no-fast-forward for features
git merge --no-ff feature-name # Preserve feature branch history

# Use squash for cleanup
git merge --squash feature-name # Combine messy commits into one

# Use rebase for clean history
git rebase main # Before merging feature branch

Branch Protection Rules

# Best practices for important branches:
# - Protect main/master branch
# - Require pull request reviews
# - Require status checks to pass
# - Require up-to-date branches
# - Restrict pushes to main branch

# Example: only merge via pull requests
# Never push directly to main:
git switch main
git pull origin main # Always pull latest
# Work in feature branches only

Troubleshooting Branches

Common Issues

# Accidentally committed to wrong branch
git log --oneline -n 3 # Find the commits
git reset --hard HEAD~2 # Remove commits from current branch
git switch correct-branch
git cherry-pick abc123 def456 # Apply commits to correct branch

# Branch is ahead of remote
git status # Check how many commits ahead
git push origin feature-name # Push if you want to keep commits
# or
git reset --hard origin/feature-name # Discard local commits

# Detached HEAD state
git status # Will show "HEAD detached"
git switch main # Return to branch
# or create branch from current state:
git switch -c new-branch-name

Recovery Commands

# Recover deleted branch (if not garbage collected)
git reflog # Find commit hash of deleted branch
git switch -c recovered-branch abc123

# Find lost commits
git fsck --lost-found
git reflog --all

# Restore deleted branch from remote
git fetch origin
git switch -c feature-name origin/feature-name

Master branching and merging before exploring Remote Operations and Advanced Workflows.