There is a third option nobody seems to talk about `git merge --squash` (a squashed commit bundles commits into one commit). Which produces like `rebase` a linear commit history, but preserves the single commits.
I use git merge --squash so I can commit garbage. The garbage in the feature branch then disappears. It doesn't make sense to preserve those individual commits because they are not intended to work, they may contain code that doesn't even compile, etc. The problem with git commits is that they are immutable and exist forever so you want to get it right on your first try and every commit should be a single "unit" of change that produces a new valid version of your software. Create a feature branch, commit code (often with "WIP" as the commit message) that isn't finished yet and then git merge --squash when it's ready with a proper commit message.
By rewriting commits and using `git rebase -i`, `git commit --fixup` you can avoid the garbage and still have smaller commits that passes tests and are easy to review.
I agree - you lose the build history, ability to see the incremental changes the author intended, can't go back to the code review to see what happened on that specific commit. I have a very difficult time understanding the desire to use --squash and merge --ff. The problem to me seems like a presentation issue, not a data issue.
If you use rebase or squash merge with something like Phabricator, you can always open up the Diff URL in the commit message and see the granular history (and discussion) if you care to.