Warning potentially dangerous commands ahead -- proceed carefully.
You can rebase and squash the commits locally, then push to the remote and use the --force
option to overwrite the remote history (Note: for this to work, your GitHub repo must allow force pushing)
On your local repository, run:
git rebase -i HEAD~3
The above will allow you to mark the last two commits as fixes and swash them all into a single commit.
Then, if all looks good locally, you can run:
git push --force
The Git manual has a nice explanation of your options for rewriting history. You should definitely go read that before you go forward with this.
But you really, really shouldn't do this unless the commits contain sensitive information that you don't want on GitHub. And definitely, don't do this if the repo is public with multiple contributors.
It's usually not a big problem to have some commits in the history that were wrong.