When a single developer if working on a feature in their own feature branch, and using that branch also as a backup (e.g. pushing "going to lunch" commits), there should be no need for anyone else to pull this branch when the work is unfinished and ongoing.
Well, they can pull it to e.g. take a look at the code, but as long as they contribute to the branch themselves (and why would you base your work on someone else's "going to lunch" commit?).
If a group of people works on the same feature, then they should set up a "master-feature" branch, in addition to their personal branches.
But before I share that work with anyone, it needs to be squashed and then broken out into a logical progression of cleaned up commits with good descriptions that are bisect friendly.
By all means use the power of Git to give you great freedom while coding locally -- but don't push the resulting cruft to shared repos.
I personally prefer to rebase on a new branch, naming the new branches with a suffix in the form "-vN". Would something go wrong with the rebase, it will be way simpler to reset the new branch to the head of the old than to recover from the reflog. Nowdays I rely heavily autosquash, interactive add, interactive rebase and Magit (which makes the later two a breeze).
a) Never change pushed history
b) Have the Pull Request act as a single source of what changed in each feature branch. Since Stash also includes comments from code review, we find it offers more context than straight commit history
c) Don't have to worry about team commit-early-commit-often vs. team commit-only-when-it-works-perfectly. The changes will all be centrally documented in the PR, no matter the individual styles
I'm confused though -- I thought that if you rebased & squashed something after you pushed it, then it would confuse the git clients of anybody who had pulled before the squash?
Thanks so much for all the suggestions!