DEV Community

Git Merge vs Git Rebase

Nesha Zoric on May 28, 2018

Git merge and rebase serve the same purpose – they combine multiple branches into one. Although the final goal is the same, those two methods achie...
Collapse
 
jillesvangurp profile image
Jilles van Gurp

Simple solution: disallow rewriting history on your server (aka. git push --force MUST not be allowed, ever). This will prevent people from pushing rebased history.

It's considered good behavior to rebase before you create your pull request. Lots of OSS projects will insist on this. You decide this before you push local changes. And in the case of OSS projects it is up to them whether they will pull your changes.

Avoid doing squash merges unless you can afford to get away with them. That means you don't want to have multiple long lived branches having to deal with solving conflicts on insanely huge diffs resulting from somebody squashing huge amounts of changes. With a normal git merge, you solve conflicts commit by commit, this is great because the scope of these is usually fairly limited meaning conflicts are typically straightforward to deal with.

If you squash two weeks of work into one commit, it's like saying "we don't give a shit about versioning here; enjoy this huge diff without any context whatsoever". Don't do that. This will cause lots of work in long lived branches when they need to sync up. So, squash if you absolutely must but be mindful of the havoc you create upstream with your huge diffs. I tend to not use them. Not worth the problems they cause.

Related to that, keep any branches you care about up to speed with what they eventually have to be merged back to. Bi-directional merges just work in git and long lived branches are why you need them. Don't be afraid to use them. Knowing things will merge cleanly because you already merged the upstream changes and solved all the conflicts, is a good thing.

You might argue that feature branches are bad but the reality is that pull requests stay open for hours, days, or in some cases weeks while people collaborate on them. Shit happens in between when you create a PR and when you merge one. The bigger and more complicated your project, the more this will happen. Git was designed to facilitate this, not obstruct it. Use it properly.

Collapse
 
samipietikainen profile image
Sami Pietikäinen

Simple solution: disallow rewriting history on your server (aka. git push --force MUST not be allowed, ever). This will prevent people from pushing rebased history.

We use strategy where force push is disallowed for main branches (e.g. master) but allowed for individual developer branches. This way developers can commit freely and the history can be cleaned up before the changes are taken to master (while also being able to push the intermediate work to remote).

Collapse
 
alephnaught2tog profile image
Max Cerrina

If you squash two weeks of work into one commit,

😱

Collapse
 
neshaz profile image
Nesha Zoric

Hey, Jilles, thank you for sharing your opinion with the community! Kolosek team mostly works around feature branches and pull requests with weekly sprints. Our goal is to achieve the best results in a timely manner by keeping the features small enough to be completed on time and easy to bug fix in case that is needed.

Collapse
 
victoria profile image
Victoria Drake

For someone working alone, rebase isn't a big deal. If you're working with a team or on a public repository, I just don't see any benefit to striving for a linear history. Squash commit + merge is easy enough to read, and much safer.

A comparison I would rather make is between the git branching model and the GitHub Flow models, the former I think better for large teams, and the latter for simpler projects.

Work to suit the project, not the commit graph aesthetic. :)

Collapse
 
sohail05 profile image
Sohail Aj.

Sweet, I was looking into this exact topic on the week it was written!
The default behaviour on most services will create "merge commit" when pushing or using the web interface.
Would be great if there are ways to configure those behaviors with a github.yml/gitlab.yml or something.

e.g. Github client only has merge for branches.

Collapse
 
mbtts profile image
mbtts • Edited

Thank you for writing - I agree merging makes more sense and I would go as far to say it is a design mistake for a version control system to even allow for history/commits to be altered or overwritten (maybe unpopular opinion).

Likely even more unpopular and controversial... every time I read a git article (and this is in no way a criticism of this article in particular, which I think is well written) I am reminded that we need something better than the user hostile git (your using it wrong...!). I don't think version control has been solved properly yet by any tool.

That isn't intended as a negative comment - I think we can and eventually will do better. I believe that will eventually take the form of a more opinionated and conceptually simpler hybrid which combines the best points of distributed and centralised systems.

Collapse
 
neshaz profile image
Nesha Zoric

That's an interesting idea and would be nice to see it implemented in the future. The more variety the better!

Collapse
 
mugenhere profile image
Mugen

The second image on this page is incorrect (git-merge-2.png). It shows a green dot before master and after merging this with the branch. This is how the image should be after the merge:

If you were in the master branch and then "git merge feature-branch", then you get:

--()--()--|---()--(feature branch HEAD)---|
\ \
-- ()-- (green commit)--------(master HEAD)

Note that master is incremented and it contains the feature branch now. The existing master branch commits are before the merge. In your image they appear after the merge which is wrong.

Collapse
 
tobixyaren profile image
Tobias Günther • Edited

We use rebase when updating from remote and merge to keep feature branches to to date.

Changing the history is prohibited for all Devs.

Collapse
 
neshaz profile image
Nesha Zoric

Agreed. However, that is not necessarily a bad thing at all, especially when you are dealing with pull requests and feature branches. Having preserved commit history can make it easier to find and fix bugs and overall improves working on a group project.

Collapse
 
pajarisa profile image
i.

Good post! I'm kinda new to Git and I also think that Merging is the safer and easier way when you're working with a team that develops very similar features or features that are very related to each other. One question I still have is what should I do when I'm done with the "feature" branch? should I delete the branch and continue working in another one? or will that affect the repo history?

Collapse
 
c3phas profile image
c3phas

When you have already merged your repo to the master you can just delete the branch.

Collapse
 
lexlohr profile image
Alex Lohr

Working with shared repositories requires discipline anyways. Either be mindful if you change your branch history, avoid it altogether or face the consequences.

Collapse
 
neshaz profile image
Nesha Zoric

Yes, you are entirely right. This becomes even more important when you work on group projects!