If I see a ton of commits like "fixing formatting" or "oops", I want those squashed away into proper commits.
If the changes you make are atomic in their own right and I can check out that commit, compile it, then run tests, and it passes. That's perfect. It works good for git-bisect, but the trick is to get everyone on board in the project to do that.
For public libraries I maintain, it's squash merges all the way. I like a clean history and the ability to check out that commit, compile, test, and run cleanly is perfect.
Every team I'm in I strongly advise against such commits honestly. They don't help anyone, I emphasize being able to find things you changed if you need to find them. You can even enforce a format for commits.
Funnily enough, I saw a wave of "fixes bug" "now really fixes bug" that got auto rejected by some commitcop utility at a former job, the guy was freaking out cause it wouldnt take all his changes. I guess they wanted to force him to stop doing such awful commit messages.
Commit messages should be useful and historically descriptive.
Same with me, but people still ignore it.
As opposed to a series of small commits, that would make git bisect actually useful.
Before this there was some work to bring the codebase as close to 3.x paradigms as possible.
As long as the two points before and after the work are copacetic we were satisfied. In that sense it was discreet.
This is impossible to enforce or guarantee at scale. Squashing PRs, though, is practically fool-proof: PRs already represent a single, atomic unit of work that passes all CI checks and is safe to merge. No such thing is true (or should be!) of individual commits within that PR. Whether we like it or not, a branch commit really only represents a "save point" for a developer.
I'm not sure 100% of the commits compile & pass all tests - there may be some mistakes - but generally we're in a pretty good state, and the clean git log is being successfully used for bisecting.
If you want even larger scale - if I understand correctly, the Linux kernel practices a similar thing, which is where we got this practice from (ScyllaDB founders came from kernel development). And since Git was originally created to help developing Linux - that's where you want to look for good practices.
Sure, you can git bisect to the exact commit that introduced a bug, but that commit was part of a larger PR, and you probably can't revert just that commit alone. So what was gained?
git revert MERGECOMMITHASH -m 1 # revert to first parent of merge (revert changes of second parent/other branch)
You can include good descriptions in your PR merge commits including discussion comments and everything. Some PR tools automate that, some do not. I don't know any technical reason why any PR tool automation would create better squash merge commit messages than normal merge commit messages.(ETA: Also you may want to reconsider your workflow if you rely on reverts that often. I had to look up the command argument, even though I knew it existed, because I haven't needed to do it in a while and I'm very thankful for that.)
One thing squash and merge does is make reverting trivial.
A PR doesn't necessarily have to be a single commit to be a good PR. Sometimes, it makes sense for a PR to have several atomic commits.
Those tiny messy commits should be fixed-up into the atomic commit that they are fixing.
From the Git CLI, without any reference to Git* platforms, it is not so obvious when searching for a commit that introduced a bug, e.g. using "git bisect" for binary search. Reading a 10,000 lines git diff can be harder than a smaller commit that also explains the reasoning in the commit message. Speaking from own experience and programming mistakes in a small team, focussing on clean commits and a good history tremendously helped in stressful debug situations. Until you hit a compiler regression bug, but that's a different story then ;)
I'm personally still very fast on the Git CLI, but I also know that there are a variety of CLI and UI tools out there that can help with analysing large Git commits. Potentially in the future also AI assisted that tell us which change a diff caused a performance regression in a release 5 months later. Or we don't need it at all because Observability driven development enabled to see these problems before merging and code reviews, e.g. the memory leak but only when DNS fails. True story from ~2016, more in my KubeCon EU talk at https://www.youtube.com/watch?v=BkREMg8adaI and project at https://gitlab.com/everyonecancontribute/observability/cpp-d...