0%
Tutorial 4 of 10
40% complete

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.

mainfeature-bInitialFeature AFeature B-1Feature B-2HotfixRelease

Core Concepts

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
mainfeatureABCD

Three-Way Merge

When both branches have changed:

git merge feature/login-system
mainfeatureABCDEMerge

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
mainfeatureABCDEC'D'

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 code
  • develop: Feature integration
  • feature/*: New features
  • release/*: Release preparation
  • hotfix/*: 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 code
  • feature/*: 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
  1. Always start from an up-to-date main

    git switch main
    git pull origin main
  2. Create short, focused branches

    git switch -c feature/specific-task
  3. Make frequent, atomic commits

    git commit -m "feat: add specific functionality"
  4. Test before merging

    # Tests, linting, etc.
  5. Clean up after merging

    git branch -d feature/completed-task

Avoiding Common Mistakes

  1. Don’t develop directly on main
  2. Always check the current branch
  3. Resolve conflicts carefully
  4. Don’t force push after a rebase
  5. 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