I needed to understand the two methods because I’ve always used the merge method, thinking that the rebase wasn’t efficient or dangerous based. I’ve read.
But the truth was more nuanced.
The choice between rebasing and creating merge commits depends on your specific needs and workflow. So let’s review what each method brings.
Rebase Benefits
The first thing you read about rebase is that it creates a cleaner, linear commit history. In fact, rebase allows you to rewrite the history.
Finally, it eliminates unnecessary merge commits, you know the “Merged from PR xxxxxx” messages after you’ve merged a feature branch into develop.
Merge Benefits
First, merge method will preserve the complete repository’s history. Hence, it makes it easier to track feature implementation.
It also makes conflict resolution easier, though I came to learn how to perform a rebase with little conflict resolution difficulty.
Then, it’s easier to undo if mistakes occur.
Finally, it maintains accurate timestamps of commits.
When to Use Rebase
The main reason I’ve seen so far using rebase is to maintain a clean, linear project history.
Also, when you deal with smaller, focused changes that need to be integrated cleanly, you can use rebase. I’ve looked at the commit history of several open source projects and in none of them did I see a “Merged PR xxxx” commit message.
When to Use Merge
Though it’s recommended not to have long-living branches, using merge is a better option in this scenario.
Also, when multiple developers are collaborating on the same branch, this method makes it easier to work. Again, that really depends on what you’re doing because, with a team working on distinct features, each individual should almost always work on a distinct branch, specific to a given feature and bug fix.
Also, merge doesn’t rewrite history, like rebase does, so use when you need to preserve the exact history.
Some have said when you want simpler conflict resolution, using merge will help. Though I believe that you can resolve conflicts easily with rebase using squash on your feature branch. That applies to the case when you want to update your feature branch that is behind develop. Yes, squash to combine multiple commits into a single.
If you really want to keep your atomic commits, if you use that commit method, then yes, merging develop into your feature branch may be more challenging to resolve conflicts. However, atomic commits don’t mean one commit per file, which I believed to be a few years ago.
Best Practice Recommendations
If you’re ever in doubt, it’s recommended to use merge instead of rebase due to its lower risk and easier recovery options. However, if you’re working on a feature branch alone and haven’t pushed it to remote yet, consider rebasing to clean up your commits before creating the pull request.
Remember that both approaches will successfully integrate your changes—the main difference lies in how the project’s history appears and how conflicts are handled.
Practical Examples
I’ll provide a complete series of steps covering the various use cases when to use rebase and merge with the hypothesis that :
- we work on a simple git repository a single text file
- we want to emulate a big team with parallel feature development
- we want to test a revert
Initial Setup
|
|
Scenario 1: Feature Branch Development
|
|
Scenario 2: Parallel Feature Development
|
|
Scenario 3: Interactive Rebase for Cleanup
|
|
Scenario 4: Revert With Merge
|
|
Scenario 5: Revert With Rebase
We can have three variations of this:
Method A: Interactive Rebase to Drop Commits
|
|
When the feature hasn’t been pushed to a shared repository, or you have a team agreement to rewrite history, this method can be used.
Method B: Rebase onto Earlier Point
|
|
This variation helps you remove a specific commit and keep everything else, especially with a complex history.
Method C: Rebase with --onto to Remove Middle Commits
|
|
We use --onto when you need surgical precision to remove a range of commits from the middle of your history.
Scenario 6: Complex Rebase with Conflicts
|
|
Important Rules
- Never rebase branches that others are working on
- Create meaningful commit messages
- Always test after rebasing or merging
Sources
Here are some articles and forum threads that I looked at on the topic. Do take the time to read them as well.
- https://www.tempertemper.net/blog/git-rebase-versus-merge
- https://docs.github.com/en/repositories/configuring-branches-and-merges-in-your-repository/configuring-pull-request-merges/about-merge-methods-on-github
- https://stackoverflow.com/questions/804115/when-do-you-use-git-rebase-instead-of-git-merge/64319712
- https://www.gitkraken.com/learn/git/problems/git-rebase-vs-merge
- https://www.aviator.co/blog/rebase-vs-merge-pros-and-cons/
- https://blog.mergify.com/git-merging-vs-rebasing-the-complete-guide-for-modern-development/
- https://softwareengineering.stackexchange.com/questions/309919/merge-vs-rebase-pull-requests-on-github
- https://www.atlassian.com/git/tutorials/merging-vs-rebasing
- https://blog.git-init.com/differences-between-git-merge-and-rebase-and-why-you-should-care/
- https://www.atlassian.com/blog/git/written-unwritten-guide-pull-requests
Conclusion
If you want an interactive Git learning experience, I recommend Learning Git Branching website. It’ll guide you, step by step, in a CLI-like web interface, to learn the ins and outs of Git.
Photo by Hasan Albari.