Anyone have strong opinions about only allowing squash commits, vs allowing merge commits?
Having used both professionally, I don't think the benefits of squash commits only outweigh the hurdles for new developers. Merging is just easier, and I don't think the merge commits in master are really all that jarring?
That gets tricky too - what about features being developed by multiple engineers? Generally, I create a branch that embodies the full scope of work and devs treat that as the default branch while working on it - merging their branches into that one. That branch needs to be consistently rebased to be kept up to date in order to avoid conflicts, and devs will sometimes need to merge or rebase their own branches based on that branch. Usually, this isn't too complicated, unless someone buries their head in the sand for a little too long (pun intended.)
This also means that all CI jobs have to be configured to use the current branch rather than a static target - which makes logic a bit more complicated when dealing with things like E2E tests that create real environments.
What does it accomplish? A linear, well-constructed history and it ensures resilient CI jobs. The other side of that, is that the real product branch gets a very organized history, while feature development branches can have non-standard commit messages like, "I screwed up", and can allow force pushes that can't be done on my default branches. This allows for both clean history and me to not be policing people's commit messages. If you value none of those things, it's a total waste of time and energy.
This might be the case for me. I work on a relatively small dev team and luckily everyone has adhered to meaningful commit messages without needing any manual intervention.
I could imagine a time where this team is much larger and the commits begin to get out of hand. So perhaps my failure to appreciate squash-only repos is mainly a function of my relatively small team.
On the other hand, limiting commits to do a single thing and having several per merged branch allows one to revert a problematic commit without conflicts or isolate a bug using git bisect.
less work than dealing with squashing, and easier to understand past branches than the default