Git Rebase and Merge
π§© Git Merge Methods Explained
πΈ 1. Fast-Forward Merge
π What:
Moves the branch pointer forward because there’s no divergent history.
π§ͺ Example:
git checkout main
git merge feature-branchβ
If main is behind feature-branch but has no new commits, Git just moves main forward β no merge commit is created.
π Result:
- No extra commit.
- Clean history.
- Only possible when histories are linear (no parallel commits).
πΈ 2. Three-Way Merge (Default)
π What:
Used when branches diverged β Git creates a merge commit.
π§ͺ Example:
git checkout main
git merge feature-branchπ If both main and feature-branch have new commits, Git creates a merge commit to tie them.
π Result:
- Merge commit created.
- Retains full history of both branches.
- Good for preserving commit context.
πΈ 3. Squash Merge
π What:
Combines all commits from the feature branch into a single commit on the target branch.
π§ͺ Example:
git checkout main
git merge --squash feature-branch
git commit -m "Add feature X"π All feature-branch commits are flattened into one.
π Result:
- Clean, single commit.
- Good for simplifying history.
- Loses detailed history of feature-branch.
πΈ 4. Rebase + Fast-Forward
π What:
Rewrites feature branch history onto base branch β keeps history linear and avoids merge commits.
π§ͺ Example:
git checkout feature-branch
git rebase main
git checkout main
git merge --ff-only feature-branchπ Keeps history tidy and linear.
π Result:
- No merge commits.
- Linear history.
- Can be risky if rebasing shared branches (changes commit hashes).
πΈ 5. No-Fast-Forward Merge (--no-ff)
π What:
Forces Git to always create a merge commit, even if a fast-forward is possible.
π§ͺ Example:
git merge --no-ff feature-branchπ Use this to clearly show a branch was merged, even if no divergence.
π Result:
- Always a merge commit.
- Good for clear separation of features in history.
π Summary Table
| Merge Method | Merge Commit | History Type | Use Case |
|---|---|---|---|
| Fast-Forward | β No | Linear | Simple updates |
| Three-Way Merge | β Yes | Diverged | Default for complex merges |
| Squash Merge | β One commit | Simplified | Clean history, single logical change |
| Rebase + FF | β No | Linear | Clean history before merge |
| No-FF | β Yes | Always visible | Always document a merge explicitly |
π§ Best Practices
- β Use squash for feature branches in solo/team projects to simplify history.
- β Use no-ff in protected/main branches for clear audit trails.
- β Use rebase to clean up local commits before merging.
π Understanding git rebase
πΉ What is git rebase?
git rebase is used to move or combine a sequence of commits to a new base commit. It is often used to maintain a cleaner, linear project history.
Unlike merge, which creates a new commit, rebase re-applies commits on top of another branch.
πΉ Syntax
git rebase <upstream-branch>Example:
git checkout feature
git rebase mainThis reapplies your feature branch commits on top of the latest main.
πΉ Common Use Case: Updating Feature Branch
# Assume you're on feature branch
git checkout feature/login
git fetch origin
git rebase origin/mainβ This puts your feature branch on top of the latest main, as if it was created from it.
πΉ Resolving Conflicts During Rebase
If conflicts occur:
# After editing the file to fix conflicts
git add <resolved-file>
git rebase --continueTo skip the current commit:
git rebase --skipTo abort the rebase and return to the previous state:
git rebase --abortπ Interactive Rebase
Use this to edit, squash, or reword commits.
git rebase -i HEAD~3Example interactive menu:
pick 3f5e1f9 Added login form
pick 89d2ac3 Fixed typo in login
squash d14e7a3 Updated form stylesChange pick to:
rewordβ change the commit messagesquashβ combine commits into oneeditβ pause to change code during rebase
π Rebase vs Merge
| Feature | git merge | git rebase |
|---|---|---|
| History | Keeps history with a merge commit | Creates a linear history |
| Commit Graph | May look like a tree | Looks like a straight line |
| Use When | You want to preserve all changes | You want a clean history |
π« Donβt Rebase Shared Branches
β οΈ Avoid using git rebase on branches that others are working on (i.e., already pushed/shared), unless you coordinate with your team.
π§ Example: Clean Up Before Merge Request
git checkout feature/payment
git rebase -i HEAD~5
# squash into a single commitThen:
git push -f origin feature/paymentπ‘ Tip: Use
git log --oneline --graphbefore and after rebase to visualize the change.