loading...

Rebase or merge

booorkoo profile image Borko Arsovic 🚀 ・1 min read

I don't have a lot of experiences with git. I mostly used merge, but I have a suggestion that rebase is better. People on internet are divided, one says one thing and the others say the other.

What do you think?

Discussion

markdown guide
 

It depends.

If you are the only person working on a branch and you haven't made a PR for it yet (and that nobody reviewed or commented on the said PR), you can and should rebase your work. It keeps git history clean and makes resolving a merge conflict easier. But you will need to force push your work (assuming you already pushed it) because it basically rewrites your commit history.

For every other scenario, you would use merge. So if you are sharing your branch with someone, merging will retain you and your collaborator's commit history.

And if you are really not sure about any of this, merging is the safest way to go about it.

 
 

My current preference is to rebase feature branches, then merge those using --no-ff. This makes sure there are no conflict resolutions in the merge commits (because those were resolved while rebasing), but still groups related commits together.

 

This.

We have a master and develop branch. And when I'm writing a feature in say... "myBranch". I will rebase develop onto my branch then merge back into develop using git checkout develop; git merge myBranch --no-ff.

 
 

I might be restating what is already known. But the difference between rebase and merge is that in rebase your commits are put on top of the branch being merged while in merge a seprate new commit is created to merge the two branches. Now, I know it doesn't help but had to get basics out of the way. Lets see with an example.
Suppose there are two branches where first brach has commit A, B and C and second branch has commit D and E. So initially the repository will look something like:

X ┬ A - B - C
  └ D - E

Now, if you rebase second branch, all its commits will be put on top of fisrt branch.
This is done by simply changing parent commit of D from X to C and then moving subsequent commit on top of it. So the end result will look something like.

X - A - B - C - D - E

While, during merge, a new merge commit Y will be created to combine two branches. So, final result in this case would be:

X ┬ A - B - C -┬ Y
  └ D - E -----┘

Now, people prefer rebase as it results in very clear history (straight line). While in merge, if done very often, the history becomes unreadable because of frequent branching for just 1 or 2 commits.

So we should always rebase right? No!

Because in rebase, all your commits are put on top of other branch one by one. So, if there are some conflicts, then you might end up fixing conflicts for each commit. Imagine doing 10 conflict resolution for 10 commits. While in merge you have to do it only once.

So coming back to original question, when to rebase and when to merge?

There is no hard rule for it, however :
If I have to push just a few commits for some minor non-related changes (bug fixes) then I prefer to rebase.
If I a working on a new feature which tends to have a lot more commits and probably changes which might got reverted / rewritten later in the branch. It makes sense to do a merge. Also, in this case, the history kind of group these feature realated change together in seprate branch.

But again there is no hard rule.

 

Rebase onto current tip of target branch before pushing. Merge after review.

 

IMO, ideally you would use both. Create a branch and make commits for your changes, but when you are ready to add those changes back into 'master', you should first rebase. This illuminates any diffs from the current standard and the changes you have made, including any branches you have merged into your working branch. When the PR is approved, you can then squash commit so there is a single commit with all the changes you have made.

 

I find it more straightforward and less error-prone to suggest merge as the default strategy. Team-members who are very comfortable with git can use rebase for a cleaner history. The problems with making rebase the default policy are:

  • Team members must be mindful of when a rewritten commit history would be problematic. Force-push must be enabled on the remote, and you should be sure nobody is referencing your branch.
  • When you resolve conflicts during a rebase, you resolve each commit independently, which can be more work than just resolving a single merge commit.

That said I like doing rebase myself in many situations.

 

It is very easy to create a mess with merge. It's almost always ok when you're working alone, but the moment you have to share, it is much more practical to have linear history. I've seen repositories consisting only of merges, because two developers just pulled and pushed from the central repo. You know, when you pull by default it creates a merge commit if it is not possible to do fast forward, and you can push it, and then everyone on the project will see that commit, and when they pull each of them could potentially create a new commit, and push it and so on.

I find linear history easier to navigate. You don't need anything fancy, just a simple git log will do just fine.

If you use merges on your local repo and you try to rebase your work on some other branch, you're in trouble. That's not an easy job. And it might be possible that you'll be required to rebase.

So, I prefer rebase/fast-forward policy on all my repos. :)

 

For me, what matters is the origin version of the branch I'm working on. That means that I'll rebase locally, so that my own changes are always added on top of the origin branch. So while it's true that rebasing tends to change your history, your local history is mostly irrelevant; it's the origin's history that counts, and merging changes that while rebasing does not.

That said, what I'm talking about here are a few local commits. If you're working with a long-lived branch, and you need to add the changes made in that branch to (e.g.) the master branch, then merging makes the most sense, since rebasing might add more complexity to the process (compare that to local commits, which should never ever be 'long lived').

 

I think it depends on the team and the tool. Rebase is not very conplicated I think. It makes a cleaner history highway. But I think when you work alone this makes bi sense. It depends on your collegues too, because ehe you are the only one that use rebase it does not help to make the history highway cleaner. So it depends on your team and if you alone and if the tool you use helps you with merging conflicts.