I would advocate for using each tool, where it makes sense, to achieve a more intelligible graph. This is what I've been moving towards on my personal projects (am solo). I imagine with any moderately complex group project it becomes very difficult to keep things neat.
In order of expected usage frequency:
- Rebase: everything that's not 2 or 3. keep main and feature lines clean.
- Merge: ideally, merge should only be used to bring feature branches into main at stable sequence points.
- Squash: only use squash to remove history that truly is useless. (creating a bug on a feature branch and then solving it two commits later prior to merge).
History should be viewable from log --all --decorate --oneline --graph; not buried in squash commits.
Mustard only?! I am definitely the dog in the hot dog car.