John took Mary back and forgave her because she’s in his head and heart a lot like Sherlock is, and he would do (did do!) the same for Sherlock.
John is a really hugely fucked-up puppy. And I love him that way.
ETA: As Dee points out, John also did not take Mary back immediately. That jump went from sometime in the early fall at the latest, to Christmas. So John took at least three months to decide how he felt about Mary—and he had barely talked to her in all that time.
He forgave Sherlock a lot faster. (Then again, Sherlock had not shot his best friend.)