rebasing means that you end up with a new version of code that you have never tested, and it's impossible for anyone looking at the resulting tree to figure out what you developed against.
The 'right' way to do things is to have a branch that you use to track the upstream version, one or more branches that you do development in, and then you create test branches to test merging your work with the upstream work (rather than merging directly into your development or upstream branches). After you test the merge, you delete the branch, you defiantly don't do any more development on it.
only when you are ready to push do you do a merge that will be visible to the outside world and push out.
the excess merge commits that you are bothered by are an indication of real problems, but rebasing instead isn't any better.