I’ve used git successfully professionally for almost 10 years and I’m not lying when I say I’ve used rebase about 5 times. We just merge. We squash sometimes. I think it must be because I’ve always worked in smaller orgs but rebase just seems to always be over complicating something simple (a merge). I get that there’s a benefit of a cleaner history but to me the benefit of simplicity merge offers makes it superior
It feels like overindexing on git as a source of truth for the iterative development process itself is just bikeshedding. Do whatever you want to do locally, then squash your commits into a single unit change. Document that comprehensively in your commit message for that squashed change. If there was some profound learning that feels like it needs rebase history for, just explain it narratively.
Perhaps a more contentious take: rebasing doesn’t bring any real value. To the original comment above, I would say a significant percentage of teams never use rebase and drive business value just fine. I do not think there exists and evidence to suggest teams that use rebase over squash merging are in some way higher performing. Rebase is something that some people’s obsessiveness compels them to care abut because they can, and then retroactively justify their decisions by suggesting value that isn’t there.
I don't get why people like rebasing as an alternative to merging. It works kind of OK for small histories, but if you do something slightly complex or your history is not meticulous, rebasing becomes extremly tedious. The worse example is a conflict in a reverted commit. A merge will flatten the diff and skip the reverted commit entirely, while a rebase will require you to fix the conflict twice. And while a merge is tedious to revert, it is possible. Good luck saving a branch ravaged by a bad rebase.
My only beef with rebasing is that it seems to fail much more often, whereas merges will usually do the right thing. I realize this is git-specific, but rebases have still given me much more trouble than merges.
Merge conflicts, history readability, and PR readability are just the things that rebase helps with. I understand, I have coworkers who said "keep things simple; you shouldn't have to be an expert in VCS" as if learning how to use your tools is a bad thing! It's not like Git even takes that long to master.
Rebase is a lot more than a merge strategy. Merging is only one of the things it can do. Rebase -i allows you to rewrite history, and if you rewrite history of shared code, it leads to all sorts of issues with git.
In my case, I switched rapidly to git-rebase because it produces history that is much cleaner and easier to understand. I only do merge if there is a good reason to preserve history (e.g. some other branches depend on it, or some test reports refer to a given commit).
Rebase is nice if you have very careful code review policies. Otherwise, if you don't have humans carefully reading every merge, it is a huge waste of time.
Rebasing also increases the number of conflicts you will have to resolve. I've seen this 'always rebase' advice over and over in the last few years, it's stupid advice that betrays a lack of understanding about how git works. There is no advantage whatsoever unless you also squash your commits, and even then there is no advantage unless you are submitting to a project with very careful code review practices (Linux kernel, a project that uses the gerrit code review tool, etc).
Wouldn’t you have the same amount of merge conflicts with rebase? Especially if you don’t do it often, which you frankly also should with merge?
I have to admit that I never really understood the advantages of rebase, and what I mean by this is they I actually don’t understand how the dangers of rebase out-weighs any form of advantages. Especially because on of the major advantages of merge is that you can squash your local commit history when you submit it to your main branch.
What we do is that we tie every pull request to a relatively small feature task, and because we do this, we genuinely don’t care about the individual commits developers do. Which means they can commit really silly messages if they are heading to a meeting or if they are just tired at the end of the day. It also helps with them merging main into their branch often, because it doesn’t taint the history.
The biggest advantage we’ve seen, that maybe we didn’t expect, is that nobody ever fucks up our tree in a way that needs someone who actually understands git to solve. We’ve also locked down the use of force push so that is not available to anyone unless it’s absolutely needed. Part of the reason I set this up initially was to protect myself from me, but it’s been a good thing since.
In my experience- as opposed to merging, which just works, but nerds get all persnickety about because they hate merge commits. I understand the concern I suppose, but working with `git rebase` just seems so unnecessarily painful. It's really awful.
There are two major things I really gain out of rebasing frequently.
Firstly and most importantly, Thanks to rebase I'm constantly working against the most recent mainline, merge pains are reduced by frequently dealing with smaller rebase merges instead of trying to do one massive merge at the end when I'm finished with a longer life task that might last a week or two. The more often you merge the less painful it is.
Secondly there's the cleaning part of history involving squashing. I believe the issue with your viewing the merge history of the main line will miss out on changes that were able to be introduced fastforward without a merge. And frankly no one else on the team cares that I committed 6 times in the process of one task, they want to see all the code relevant to that task, and ideally it's all in one change set.
I feel like squash-merge accomplishes what I want (easy revertibility and simpler history). I'll admit I need to learn it better, but every time I've tried to use rebase I feel like I'm playing with fire and I end up doing silly things like making a backup of the whole folder. I just think the process is unintuitive and somewhat scary, and I don't get the net gain. Like, outside of looking at the last couple days is anyone really spelunking into history that much anyway?
Merging rocks! Never had an issue with merging and it’s less work. I’d only rebase if there is a “story” I want to tell in the commit history, that would be otherwise lost. This is rare, probably if someone else did some major refactor or move around
Rebase is not simpler in any context - rebase rewrites history, which, if branches have been pushed to remotes, then necessitates force pushes, which in turn breaks any other instances of the same branch. By using rebase to "keep history clean" you are largely undermining git's power as a DVCS.
Rebase as a tool is not inherently bad but it is definitely not simpler than merge - it introduces additional considerations, requires a deeper understanding of git for effective use and is a dangerous tool in the hands of people who do not understand what it is doing and in my experience most teams that are using it as a core part of their workflow are doing so for the wrong reasons (generally because of a fundamental misunderstanding of how branching and merging works in git and why it works that way).
I understand there's a whole lot of FUD behind rebase, but I still don't like it. To me, a project's branch structure provides a history of how it all went down, and when I'm trying to hunt down a mysterious change in the code, it's all information I can use to figure out exactly why a certain decision was made, and whether it was made on purpose or by accident.
I think rebase and squash go together in terms of what you want to get out of the VCS. If you want a clean history, where every commit represents a complete feature, with the knowledge that you can check any commit out and expect it to work, then squash and rebase are your friends. If like me, you want to understand the history of the code, warts and all, then merge is the way to go.
Also, I find I can achieve most of the benefits of a rebase workflow by just defaulting to git log --first-parent.
I'll admit as a 20yr c++ developer, I don't know what rebase is or when to use it. I've only been using git for a few years, cvs before that. I commit and push often, then do a merge request via a web portal gui(bitbucket or gitlab), then merge it squashing commits again using the gui.
Using rebase results in a cleaner history and simplified workflow in many cases. However it also means that when you have a disaster, it can be truly unrecoverable. I hope you have an old backup because you told your source control system to scramble its history, and you don't have any good way to back it out later.
For those who don't know what I mean, the funny commit ids that git produces are a hash signifying the current state of the repository AND the complete history of how you got there. Every time you rebase you take the other repository, and its history, and then replay your new commits as happening now, one after the other. Now suppose that you rebased off of a repository. Then the repository is rebased by someone else. Now there is no way to merge your code back except to --force it. And that means that if your codebase is messed up, you're now screwed up with history screwed up and no good way to sort it out.
That result is impossible if you're using a merge based result. The cost is, though, that the history is accurately complicated. And the existence of a complex history is a huge problem for useful tools like git bisect.
`git rebase` is fairly useful when differences are small. Rebase changes the history of your own commits. When that history is long (you've got a lot of commits that are not in the other branch), you'll end up resolving the same conflicts over and over and over again, and in that case, a simple merge is much less painful.
The only real advantage of rebasing is that it keeps your history linear. A history with merges is harder to navigate. But at some point, merges become unavoidable, and the larger the differences are, the more important it becomes to use merge instead of rebase.
And as any time traveler knows, changing history comes with risks.
reply