Branches and Merging
Learn how to create branches to work on different features and merge them into your main codebase.
Branches and Merging
Branches are one of Git’s most powerful features. They let you develop features in parallel, experiment without risk, and keep a clean history. This tutorial will teach you how to master branches and merging techniques.
What Is a Branch?
A Git branch is a movable pointer to a specific commit. It lets you diverge from the main line of development and work on isolated features.
Core Concepts
HEAD
HEAD is a pointer to the current commit (usually the latest commit on the current branch).
Default Branch
- Historically:
master - Modern:
main - Configurable to suit your preferences
Managing Branches
Listing Branches
# Local branches
git branch
# All branches (local and remote)
git branch -a
# Remote branches only
git branch -r
# With detailed information
git branch -v
Creating a Branch
# Create a new branch
git branch nouvelle-fonctionnalite
# Create and switch to the new branch
git checkout -b nouvelle-fonctionnalite
# With Git 2.23+ (recommended)
git switch -c nouvelle-fonctionnalite
# Create a branch from a specific commit
git branch nouvelle-branche abc1234
Switching Between Branches
# Traditional method
git checkout nom-branche
# Modern method (Git 2.23+)
git switch nom-branche
# Go back to the previous branch
git switch -
# Switch, creating the branch if it doesn't exist
git switch -c nouvelle-branche
Renaming a Branch
# Rename the current branch
git branch -m nouveau-nom
# Rename another branch
git branch -m ancien-nom nouveau-nom
Deleting a Branch
# Delete a merged branch
git branch -d nom-branche
# Force deletion (even if not merged)
git branch -D nom-branche
# Delete a remote branch
git push origin --delete nom-branche
Workflow with Branches
Practical Example: Developing a Feature
# 1. Start from the main branch
git switch main
git pull origin main
# 2. Create a branch for the feature
git switch -c feature/login-system
# 3. Develop the feature
echo "function login() { /* code */ }" > login.js
git add login.js
git commit -m "feat: add basic login function"
# 4. Continue development
echo "function logout() { /* code */ }" >> login.js
git add login.js
git commit -m "feat: add logout function"
# 5. Return to main for the merge
git switch main
Types of Merges
Fast-Forward Merge
When the main branch hasn’t changed:
git merge feature/login-system
Three-Way Merge
When both branches have changed:
git merge feature/login-system
Merge with a Custom Message
git merge feature/login-system -m "Merge login system feature"
No-Fast-Forward Merge
Force the creation of a merge commit:
git merge --no-ff feature/login-system
Rebase: An Alternative to Merge
Rebase rewrites history by moving commits:
# Rebase the current branch onto main
git rebase main
# Interactive rebase to modify history
git rebase -i HEAD~3
Merge vs. Rebase
Merge:
- Preserves the exact history
- Creates merge commits
- More complex but complete history
Rebase:
- Linear, clean history
- Rewrites history
- Can complicate collaboration
Resolving Conflicts
What Is a Conflict?
A conflict occurs when Git can’t merge changes automatically.
Conflict Example
# File with conflict
<<<<<<< HEAD
function greet() {
return "Hello World!";
}
=======
function greet() {
return "Bonjour le monde!";
}
>>>>>>> feature/french-translation
Resolving a Conflict
# 1. Identify the conflicting files
git status
# 2. Edit the files to resolve the conflicts
# Remove the <<<<<<<, =======, >>>>>>> markers
# Keep the code you want
# 3. Mark as resolved
git add fichier-resolu.js
# 4. Finalize the merge
git commit
Tools for Resolving Conflicts
# Configure a merge tool
git config --global merge.tool vimdiff
# Launch the resolution tool
git mergetool
# Abort a merge in progress
git merge --abort
Branching Strategies
Git Flow
A structured workflow with specialized branches:
main: Production codedevelop: Feature integrationfeature/*: New featuresrelease/*: Release preparationhotfix/*: Urgent fixes
# Git Flow example
git switch develop
git switch -c feature/user-profile
# ... development ...
git switch develop
git merge feature/user-profile
GitHub Flow
A simplified workflow:
main: Production codefeature/*: All changes
# GitHub Flow example
git switch main
git switch -c feature/new-header
# ... development ...
git push origin feature/new-header
# ... Pull Request on GitHub ...
Trunk-Based Development
Development happens directly on the main branch, using short-lived branches.
Advanced Commands
Cherry-pick
Apply a specific commit from another branch:
# Apply a specific commit
git cherry-pick abc1234
# Apply multiple commits
git cherry-pick abc1234 def5678
Stash with Branches
# Save your changes
git stash
# Switch branches
git switch autre-branche
# Apply the stash on the new branch
git stash pop
Comparing Branches
# See the differences between branches
git diff main..feature/login
# See commits unique to a branch
git log main..feature/login
# See modified files
git diff --name-only main..feature/login
Practical Exercises
Exercise 1: Basic Workflow with Branches
# 1. Initialize a project
mkdir git-branches-demo
cd git-branches-demo
git init
echo "# Projet Demo" > README.md
git add README.md
git commit -m "Initial commit"
# 2. Create a feature branch
git switch -c feature/add-calculator
echo "function add(a, b) { return a + b; }" > calculator.js
git add calculator.js
git commit -m "feat: add calculator function"
# 3. Go back to main and create another branch
git switch main
git switch -c feature/add-styles
echo "body { font-family: Arial; }" > styles.css
git add styles.css
git commit -m "style: add basic styles"
# 4. Merge the branches
git switch main
git merge feature/add-calculator
git merge feature/add-styles
# 5. Clean up
git branch -d feature/add-calculator
git branch -d feature/add-styles
Exercise 2: Handling Conflicts
# 1. Create an intentional conflict
git switch main
echo "Version main" > conflict.txt
git add conflict.txt
git commit -m "Add conflict file from main"
git switch -c feature/conflict-test
echo "Version feature" > conflict.txt
git add conflict.txt
git commit -m "Modify conflict file from feature"
# 2. Attempt the merge (conflict expected)
git switch main
git merge feature/conflict-test
# 3. Resolve the conflict
# Edit conflict.txt to resolve it
echo "Version fusionnée" > conflict.txt
git add conflict.txt
git commit -m "Resolve conflict"
Exercise 3: Rebase vs. Merge
# Set up the environment
git switch main
echo "Line 1" > file.txt
git add file.txt
git commit -m "Add line 1"
# Branch with merge
git switch -c branch-merge
echo "Line 2 from merge" >> file.txt
git add file.txt
git commit -m "Add line 2 via merge"
git switch main
echo "Line 3 from main" >> file.txt
git add file.txt
git commit -m "Add line 3 from main"
git merge branch-merge
# Branch with rebase
git switch -c branch-rebase
echo "Line 4 from rebase" >> file.txt
git add file.txt
git commit -m "Add line 4 via rebase"
git switch main
echo "Line 5 from main" >> file.txt
git add file.txt
git commit -m "Add line 5 from main"
git switch branch-rebase
git rebase main
git switch main
git merge branch-rebase
# Compare the histories
git log --oneline --graph
Best Practices
Branch Naming
# Common conventions
feature/user-authentication
bugfix/login-error
hotfix/security-patch
release/v1.2.0
experiment/new-algorithm
Recommended Workflow
-
Always start from an up-to-date main
git switch main git pull origin main -
Create short, focused branches
git switch -c feature/specific-task -
Make frequent, atomic commits
git commit -m "feat: add specific functionality" -
Test before merging
# Tests, linting, etc. -
Clean up after merging
git branch -d feature/completed-task
Avoiding Common Mistakes
- Don’t develop directly on main
- Always check the current branch
- Resolve conflicts carefully
- Don’t force push after a rebase
- Communicate rebases to your team
Tools and Interfaces
Command-Line Tools
# View the branch tree
git log --oneline --graph --all
# Useful alias
git config --global alias.tree 'log --oneline --graph --all'
Graphical Tools
- GitKraken: Excellent branch visualization
- SourceTree: Full-featured interface
- VS Code: Git Graph extension
- GitHub Desktop: Simple and effective
Troubleshooting
Detached HEAD
# If you're in a detached HEAD state
git switch -c nouvelle-branche-sauvegarde
git switch main
Undoing a Merge
# Undo the last merge
git reset --hard HEAD~1
# Or if the merge hasn't been committed yet
git merge --abort
Recovering a Deleted Branch
# Find the commit of the deleted branch
git reflog
# Recreate the branch
git branch branche-recuperee abc1234
Additional Resources
Documentation
Interactive Tools
Conclusion
Mastering branches and merging is essential for working effectively with Git. These concepts let you work in parallel, experiment without risk, and keep a clean history.
In the next tutorial, we’ll explore GitHub, the platform that has revolutionized collaboration around Git.
Estimated reading time: 30 minutes
Level: Intermediate
Previous step: Essential Git Commands
Next step: Introduction to GitHub