When I was starting to learn Git one of the first topic to confuse me is when to rebase and when to merge? As a beginner, I'm more interested in how I should do things properly more than the technical comparison of the two. Now that I'm using Git in a regular basis I would like to give it a try at explaining when to use one over the other.
Most of the time, if you google the difference between rebase and merge you'll be presented with branch divergence, 3-way merging, fast forward merge and branch tree diagrams. These things are very important to understand if you want to be comfortable with Git VCS overtime, however, most of the time it confuses beginners when all they need to know at the moment is to know which is the right thing to do given a particular workflow.
If you want a short answer you might want to jump to the short answer section. Otherwise, read on.
I'm the only developer of the project and commit directly to main branch
If you commit directly to the main branch a.k.a. Git centralized workflow then you'll never encounter divergence so you don't need to concern yourself with merge or rebase for now.
I'm the only developer of the project but I always work with a feature branch then merge it to the main branch after
If you don't work with two or more feature branches at the same time and you're the only developer of the project then your feature branch will never diverge with the main branch. Since you're sure nobody is touching the main branch you don't even have to do a rebase or merge in your private feature branch.
When you're done with your feature branch and want to merge back to the main public branch Git will always successfully do a fast-forward merge (or commit squash if that's your thing).
There are more than two developers in the project and we are working with different branches at the same time
Your private feature branch might diverge with the main branch so you need to decide whether to do a
git pull (which is by default the same as
git fetch then
git merge) or do a
git fetch then
Before this can be answered properly you need to ask yourself first two questions:
- How's your feature branch merged to the main branch?
- Do you need merge information in your commit history log?
We're using bitbucket or github to create a pull request where a maintainer merge it to main branch using "merge squash"
If your organization is using commit squash when merging PR to the main branch then you don't have to worry whether to use
merge in your local feature branch. When your branch is merged to the main branch, all your commits will just be squashed into one single commit in the main branch. As long as you do a merge or rebase in your local feature branch to resolve potential conflicts before submitting your PR then you're good.
We're using bitbucket or github to create a pull request where a maintainer merge it to main branch using "merge commit'
Ok, now you have to worry whether to use
git merge or
git rebase. The next question to ask yourself:
- Do I or my organization want to have a linear commit history in the main branch?
- Do I or my organization want to retain merge points information e.g. ancestor branch/es?
- Do I or my organization even care of the main branch commit history whether its linear or not?
If you answer yes to question 1 then always do a
rebase in your private (non-shared) feature branch so that during merging to main branch it will always successfully do a fast-forward merge that results to a clean linear commit log history.
If you answer yes to question 2 then perform
merge in your private feature branch to update to latest changes from public main branch and resolve potential conflicts if any.
When merging to public main branch git might perform a fast-forward or a 3-way merge depending on the status of the main branch. Regardless, the main branch will capture the merge point information of all merges you did during the lifespan of your private branch but in my opinion there are very few reasons somebody will want this.
It actually depends to your organization policy as it is also feasible to
rebase your private branch and only do a
git merge --no-ff when merging to the main public branch so that merge point information appears only when merging from feature branch to main branch but not the merge information of your periodic updates from main branch to your feature branch.
If you answer yes to question 3 then your main branch commit history log might look like a jumbled mess so you can perform either
merge to your local feature branch and it won't matter.
If you found this page in google and you're in a hurry and want a rough but short answer then read on, otherwise read the long answer.
When to use git rebase
When working with your local/private (non-shared) feature branch always use
git rebase when applying updates from your source branch (usually the main branch e.g.
develop) except when you or your organization as a matter of policy wants to preserve traceability like merge points information.
Do not use rebase on a shared feature branch or it will break the work of other persons working on that feature branch!
When to use git merge
When working with a public branch such as
master always use git merge.
When working with your local/private feature branch use
git merge only when you or your organization as a policy wants to preserve traceability like merge points information.
If you are using sites like bitbucket.org or github.com to merge pull request to the main branch, it will ask you whether you want to do a commit squash or commit merge. Commit merge can be fast-forward only
merge --ff-only or
merge --no-ff which is most of the time presented as an option depending on the site you're using.
What is the benefit of using rebase in your private branch instead of merge?
Aside from applying updates from the source branch to your private feature branch, Git rebase just ensures a clean linear commit history log than git merge i.e. only if you are using merge commits predominantly fast-forward merge (
git merge --ff-only) in the public branch. That's it.
If you are using merge squash (
git merge --squash) in the public branch (e.g.
develop) then it will not make any difference since all commit logs will just be overwritten by the public branch authorized maintainer into one single commit log anyway.
I will not explain the technical details of rebase vs merge since there are several topics to that already in the Internet and I feel it will just complicate the simple answer I presented. Git is a very flexible tool and is sometimes confusing what is the best practice to doing which and when and that's what I want to answer here since I think knowing this consequently makes understanding the technical details easier.