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 really doubt that it's ever necessary to understand the intricate history of each and every developer working on a codebase to be able to track regressions. You're not Poirot.
History is an artifact of development and if it's worth keeping then it's worth maintaining. Rebasing serves to clean up the history ready for archiving (ie. merging to master), giving you a long linear line of commits that is possible to bisect to quickly find the source of regressions.
You do want to curate topics with interactive rebase, but you probably shouldn't want to destroy useful information by making everything linear. This is a common and I believe misguided thing people do when they don't know about e.g. gitk (which comes with Git, although your OS packager might split it out).
It certainly doesn't aid the bisect command at all. It might hinder it (e.g., a whole series becomes bad because you rebased it off a release tag onto some random point; bisect would pinpoint the merge if you had merged it, but you destroyed useful information so it can only pinpoint one of the diffs).
As you say, you definitely don't want to archive every weird developer fumble during development. That's useless noise that makes the history unreadable.
Yep, architecture decision records (ADRs) for the win. Just next to your README file in the repo.
But big projects seldom use rebase. This is because it's quite hard to `git revert` an entire change from two weeks before (change being e.g. 50 related commits).
Ever had a friend or editor help you with an essay? Often they’ll suggest cutting stuff out to make the meaning clearer or rewording something that was left over from an earlier edit.
I do a LOT of check ins — sometimes just for a few characters when, say, refactoring, as I want to trivially undo multi-file changes. Sometimes I do a half of implementing a feature, save, run tests, then finish the job, perhaps eliminating scaffolding erected to make the implementation work, vitally important at the time but would just end up as noise when someone wants to just see the new feature implementation.
So squashing that down to a few check ins can be more informative. Especially if the implementation took a few days so needed to catch up to the head of the tree a few times along the way.
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.